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

Hol*_*osa 7 java spring unit-testing mocking mockito

我想用Mockito对这个抽象类进行单元测试,详见这篇精彩的答案.

诀窍是,抽象类依赖于在其构造函数中注入的策略.我已经创建了一个模拟策略,我希望我的模拟BaseClass实例能够使用模拟策略进行单元测试.

关于如何连接它的任何建议?我目前没有使用任何IoC框架,但我正在考虑Spring.也许它会成功吗?

// abstract class to be tested w/ mock instance
abstract BaseClass
{
    // Strategy gets mocked too 
    protected BaseClass( Strategy strategy)
    {
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

更新:
根据Mockito邮件列表,目前没有办法将参数传递给mock的构造函数.

Hol*_*osa 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
...
Run Code Online (Sandbox Code Playgroud)

如果私人领域的名称发生变化,它会破裂,但是它的评论和我可以接受.它很简单,它是一行代码,我发现这更适合暴露任何setter或者必须在我的测试中显式子类.

编辑: 所以它不再是一行代码,因为我的私有字段需要是'final',需要一些额外的反射代码来绕过.


Kle*_*lee 5

我已经看到在春天的情境层面使用Mockito完成了这种事情.

例如:

<bean id="myStrategy" name="myStrategy" class="org.mockito.Mockito" factory-method="mock">
    <constructor-arg value="Strategy" />
</bean>
Run Code Online (Sandbox Code Playgroud)

我希望有所帮助.