19

我正在使用 Mockito 进行 JUnit 测试。因此,我要测试的代码中使用了一个给定的 A 类:

class A{

    public A(){}

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

}

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

class B{

    public B(){}

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

}

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

任何帮助将不胜感激,在此先感谢您!

4

3 回答 3

22

好吧,mockito 模拟通过扩展类和覆盖方法来工作,在你的情况下,这是不可能的A.a(String)。如果你想让这种情况发生,你必须删除 final 修饰符。

现在假设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);
         }
    };
}

请注意,这个答案是写在手机上的,可能有拼写错误或名称错误,但您应该知道应该做什么才能实现您想要的。

干杯

于 2012-08-23T09:30:23.190 回答
3

根据Mockito 限制,无法覆盖 Mockito 生成的模拟的最终方法。但是您可以使用Powermock在运行时破解代码,以便 Mockito 可以完成它的工作。

于 2012-08-23T09:27:48.313 回答
1

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

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

后来在跟踪中它指出“你存根:final/private/equals()/hashCode() 方法。这些方法不能被存根/验证。”

所以根据 Mockito 你不能存根 final 方法,就是这样。

编辑:因此,您必须删除 final 修饰符,或者,如果您坚持使用此类,请找到另一种解决方法。

于 2012-08-23T09:30:47.733 回答