使用模拟的构造函数参数模拟抽象类?

时间:2012-04-16 22:11:55

标签: java spring unit-testing mocking mockito

我想使用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邮件列表,目前没有办法将参数传递给模拟的构造函数。

3 个答案:

答案 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);

正常工作:)