java Mockito:当方法 Aa 被调用时,然后执行 Bb

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12087944/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 07:32:46  来源:igfitidea点击:

Mockito: when Method A.a is called then execute B.b

javaunit-testingjunitjunit4mockito

提问by user1448982

I'm using Mockito for JUnit tests. So there is a given class A that is used from the code i want to test:

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

class A{

    public A(){}

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

}

and i want to replace the Method call A.a with another method call with the same arguments and same type of return value. As you can see, its not possible to override the method a by extending the class as it is final. So what i have now is another class B with the method B.b:

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

class B{

    public B(){}

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

}

Now i want to make sure every time when A.a is called from the code, the return value of B.b is used instead. Is there a possibility to achieve this with Mockito (something like Mockito.when(A.a(x)).thenReturn(B.b(x));) but with the same parameter x, without knowing the value of x?

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

Any help would be appreciated, thank you in advance!

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

采纳答案by Sergej Zagursky

It isn't possible to override final methods for Mockito-generated mocks, according to Mockito limits. But you can use Powermockto hack code at runtime so that Mockito can do its job.

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

回答by Brice

Well mockito mocks works by extending the class and overriding the method, which in your case is not possible on A.a(String). If you want this to happen you have to remove the final modifier.

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

Now assuming A.a(String)is not final, what you ask is completely doable with mockito:

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

Please note this answer has been written on a phone and might have typo, or wrong names, though you should get the idea of what should be done to achieve what you want.

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

Cheers

干杯

回答by Simon Hellinger

Basically I took your setup and wrote a Unit-Test with it. What popped up first was an error message that explicitly stated this:

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

org.mockito.exceptions.misusing.MissingMethodInvocationException: when() requires an argument which has to be 'a method call on a mock'.

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

And later in the trace it states that "you stub either of: final/private/equals()/hashCode() methods. Those methods cannotbe stubbed/verified."

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

So according to Mockito you cannot stub final methods, and that's that.

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

Edit: So you have to either remove the final modifier or, in case you're stuck with this class as it is, find another way around it.

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