BaseConfigurable
你无法控制
loadConfig
是最后的,但你可以做你想做的
ConfigReferenceProcessor
正确的那么,我认为一个好的方法是用另一个层次的间接方式来区分事物。创建
ConfigurableFactory
使用
newConfigurable
方法然后可以模拟工厂并验证交互。因此,创建工厂类:
public class ConfigurableFactory {
public <T extends BaseConfigurable> T newConfigurable(Class<T> clazz, String className) throws Exception {
Class<? extends T> objClass = Class.forName(className)
.asSubclass(clazz);
Constructor<? extends T> constructor = objClass.getConstructor();
return constructor.newInstance();
}
}
然后重构原始方法:
public class ConfigReferenceProcessor {
private ConfigurableFactory configurableFactory =
new ConfigurableFactory(); // default instance
public void setConfigurableFactory(ConfigurableFactory configurableFactory) {
this.configurableFactory = configurableFactory;
}
public <T extends BaseConfigurable> T processConfigReference(
Class<T> clazz, ConfigReferenceCfg configRef) throws Exception {
T obj = configurableFactory.newConfigurable(clazz, configRef.getClassName());
// Some methods to setup and configure the new instance, including:
obj.loadConfig(configRef.getConfigName());
return obj;
}
}
像这样的东西会测试你的方法:
@RunWith(PowerMockRunner.class)
@PrepareForTest(BaseConfigurable.class)
public class ConfigReferenceProcessorTest {
// public class so the constructor is callable
public static class MockConfigurable extends BaseConfigurable {
// Mandatory methods
}
@Mock
private ConfigReferenceCfg configRefCfg;
@Mock
private ConfigurableFactory configurableFactory;
@Mock
private MockConfigurable mockConfigurable;
@InjectMocks
private ConfigReferenceProcessor processorUT;
@Test
public void shouldProcessConfigRef() throws Exception {
final String className = MockConfigurable.class.getName();
given(configRefCfg.getClassName()).willReturn(className);
given(configRefCfg.getConfigName()).willReturn("testName");
given(configurableFactory.newConfigurable(MockConfigurable.class, className)).
willReturn(mockConfigurable);
MockConfigurable result =
processorUT.processConfigReference(MockConfigurable.class, configRefCfg);
assertThat(result, is(mockConfigurable));
verify(mockConfigurable).loadConfig("testName");
}
}
然后,您可以编写工厂类的单独测试,但这些测试不需要任何模拟-只需传入值和get和instance,并检查实例的类是否符合您的期望。