Mockito:当调用方法A.a然后执行B.b.

时间:2012-08-23 08:46:00

标签: java unit-testing junit junit4 mockito

我正在使用Mockito进行JUnit测试。 所以从我想要测试的代码中使用给定的A类:

class A{

    public A(){}

    public final String a(String x){
        return "A.a: " + x;
    }

}

我想用另一个带有相同参数和相同类型返回值的方法调用替换Method调用A.a。正如您所看到的,不可能通过扩展类来覆盖方法a,因为它是最终的。所以我现在拥有的另一个B类方法是B.b:

class B{

    public B(){}

    public String b(String x){
        return "B.b: " + x;
    }

}

现在我想确保每次从代码中调用A.a时,都会使用B.b的返回值。是否有可能使用Mockito(类似Mockito.when(A.a(x)).thenReturn(B.b(x));)但使用相同的参数x来实现这一点,而不知道x的值?

任何帮助将不胜感激,谢谢你提前!

3 个答案:

答案 0 :(得分:20)

通过扩展类并覆盖方法,模拟器模拟很有效,在A.a(String)中无法实现。如果您希望发生这种情况,则必须删除最终修饰符。

现在假设A.a(String)不是最终的,你提出的问题对于mockito来说是完全可行的:

given(mockA.a(anyString()).willAnswer(returnOfB(bInstance));

Answer<String> returnOfB(final B bInstance) {
    return new Answer<String>() {
         public String answer(Invocation invocation) {
             String arg = (String) invocation.getActualArguments()[0];
             return bInstance.b(arg);
         }
    };
}

请注意,这个答案已写在手机上,可能有拼写错误或名称错误,但你应该知道应该做些什么才能达到你想要的目的。

干杯

答案 1 :(得分:4)

根据Mockito limits,无法覆盖Mockito生成的模拟的最终方法。但是你可以在运行时使用Powermock来破解代码,这样Mockito就能完成它的工作。

答案 2 :(得分:1)

基本上我接受了你的设置并用它写了一个单元测试。首先弹出的是一条错误消息,明确说明了这一点:

org.mockito.exceptions.misusing.MissingMethodInvocationException: when()需要一个必须是'模拟方法调用'的参数。

稍后在跟踪中它声明“你存在:final / private / equals()/ hashCode()方法。那些方法不能被存根/验证。”

所以根据Mockito的说法,你不能存在最终方法,就是这样。

编辑:所以你必须删除最终的修饰符,或者,如果你坚持使用这个类,可以找到另一种方法。