我有一个名为的类ConfigReferenceProcessor
,它负责实例化给定类型的新对象并使用提供的配置信息配置它们。被实例化的对象的类型必须派生自一个名为的抽象基类BaseConfigurable
(在这个基类中定义了一些方法,我需要调用这些方法来配置新实例)。向前的注释:BaseConfigurable
我无法控制,因此我无法对其代码进行任何更改。
我正在尝试对方法进行单元测试,该方法processConfigReference
执行以下操作:
public <T extends BaseConfigurable> T processConfigReference(
Class<T> clazz, ConfigReferenceCfg configRef) {
// All this in a try/catch
Class<? extends T> objClass = Class.forName(configRef.getClassName())
.asSubclass(clazz);
Constructor<? extends T> constructor = objClass.getConstructor();
T obj = constructor.newInstance();
// Some methods to setup and configure the new instance, including:
obj.loadConfig(configRef.getConfigName());
return obj;
}
在我的单元测试中,我需要控制该loadConfig
方法,因为我不想通过文件系统查找等拖入整个配置行为。我的第一个想法是简单地创建自己的模拟对象:
static class MockConfigurable extends BaseConfigurable {
@Override
public void loadConfig(String configName) {
// Do nothing.
}
// Mandatory methods
}
不幸的是,我无法覆盖loadConfig
,因为它final
在基类中声明。
我发现了有关使用 PowerMockito 方法创建模拟对象的堆栈溢出的其他问题,whenNew
并尝试使用该方法通过模拟 final 方法来设置我的模拟,并在创建新实例时返回模拟对象:
@RunWith(PowerMockRunner.class)
@PrepareForTest({ TestConfigReferenceProcessor.MockConfigurable.class, ConfigReferenceProcessor.class })
public class TestConfigReferenceProcessor {
static class MockConfigurable extends BaseConfigurable {
// Mandatory methods
}
@Mock private MockConfigurable mockConfigurable;
@Before
public void initializeMockConfigurableInstance() throws Exception {
doNothing().when(mockConfigurable).loadConfig(any(String.class));
whenNew(MockConfigurable.class).withAnyArguments().thenReturn(mockConfigurable);
}
@Test
public void shouldProcessConfigRef() {
MockConfigurable result =
ConfigReferenceProcessor.forClass(MockConfigurable.class)
.processConfigReference(configRefCfg);
// Fails!
verify(mockConfigurable).loadConfig(any(String.class));
}
}
但是这种方法似乎对我不起作用。我怀疑它不起作用,因为我实际上并没有使用new
.
有没有其他方法可以解决这个问题?