2012-04-16 163 views
6

我想使用到的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名单,目前还没有将参数传递给一个模拟的构造方式。

回答

4

我见过这种事情在春天的环境下使用Mockito完成。

如:

<bean id="myStrategy" name="myStrategy" class="org.mockito.Mockito" factory-method="mock"> 
    <constructor-arg value="Strategy" /> 
</bean> 

我希望帮助。

-1

你不需要做任何特别的事情。只是嘲笑豆正常人一样:

Bean bean = mock(Bean.class); 
when(bean.process()).thenReturn(somethingThatShouldBeNamedVO); 

只是工作:)

+0

谢谢,乔丹!不幸的是,我不认为它适用于我的情况,因为我需要注入基础的策略类中的特定模拟行为。如果使用了策略的默认模拟(仅返回null,0等),则模拟的BaseClass的逻辑将会中断。不过谢谢! – HolySamosa 2012-04-17 15:11:09

+0

这不回答这个问题。 – 2016-03-14 15:57:12

4

最终我只是使用反射来设置私有字段在我的基类,像这样:

// 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

好帖子!如果你有Spring的依赖关系,你可以用一行完成所有这些;-)。发现这个类,同时窥探春天的好东西。 'org.springframework.test.util.ReflectionTestUtils.setField(baseMock,“_privateStrategy”,strategyMock)' – 2013-09-02 23:44:50