我想使用Mockito对抽象类进行单元测试,详见great answer.
诀窍是,抽象类依赖于在其构造函数中注入的策略。我已经创建了一个模拟策略,我希望我的模拟BaseClass实例使用模拟策略进行单元测试。
关于如何连接它的任何建议?我目前没有使用任何IoC框架,但我正在考虑Spring。也许它可以做到这一点?
// abstract class to be tested w/ mock instance
abstract BaseClass
{
// Strategy gets mocked too
protected BaseClass( Strategy strategy)
{
...
}
}
更新:
根据Mockito邮件列表,目前没有办法将参数传递给模拟的构造函数。
答案 0 :(得分:6)
我最后只使用反射在我的基类中设置私有字段,如下所示:
// mock the strategy dependency
Strategy strategyMock = mock( Strategy.class);
when(....).thenReturn(...);
// mock the abstract base class
BaseClass baseMock = mock(BaseClass.class, CALLS_REAL_METHODS);
// get the private streategy field
Field strategyField = baseMock.getClass().getSuperclass().getDeclaredField("_privateStrategy");
// make remove final modifier and make field accessible
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(strategyField, strategyField.getModifiers() & ~Modifier.FINAL);
strategyField.setAccessible(true);
// set the strategy
strategyField.set(baseMock, strategyMock);
// do unit tests with baseMock
...
如果私有字段的名称发生了变化,它会破坏,但它的评论和我可以忍受。它很简单,它是一行代码,我觉得这更适合暴露任何setter或者必须在我的测试中显式子类。
编辑:因此,我的私有字段需要为“最终”,因此不再是一行代码,需要一些额外的反射代码才能解决。
答案 1 :(得分:5)
我已经看到在春季环境层面使用Mockito完成的这种事情。
例如:
<bean id="myStrategy" name="myStrategy" class="org.mockito.Mockito" factory-method="mock">
<constructor-arg value="Strategy" />
</bean>
我希望有所帮助。
答案 2 :(得分:0)
你不需要做任何特别的事情。只是像平常一样嘲笑豆子:
Bean bean = mock(Bean.class);
when(bean.process()).thenReturn(somethingThatShouldBeNamedVO);
正常工作:)