Java 同一类中的模拟方法

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/39198848/
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-08-11 20:56:59  来源:igfitidea点击:

mock methods in same class

javaunit-testingmockingmockito

提问by learningMyWayThru

I am using Mockito to mock a method in the same class for which I am writing test. I have seen other answers on SO (Mocking method in the same class), but probably I am misunderstanding them, since I running into issues.

我正在使用 Mockito 来模拟我正在为其编写测试的同一类中的方法。我已经看到关于 SO 的其他答案(同一类中的 Mocking 方法),但可能我误解了它们,因为我遇到了问题。

 class Temp() {

    public boolean methodA(String param) {

         try {

             if(methodB(param))
                   return true;

             return false;
         } catch (Exception e) {
               e.printStackTrace();
         }
    }
 }

My Test method:

我的测试方法:

 @Test
 public void testMethodA() {

    Temp temp = new Temp();
    Temp spyTemp = Mockito.spy(temp);

    Mockito.doReturn(true).when(spyTemp).methodB(Mockito.any()); 
    boolean status = temp.methodA("XYZ");

    Assert.assertEquals(true, status);
 }

I however get the expection printed out because definition of methodB gets executed. My understanding is definition of methodB would get mocked by using spyTemp. However that does not appear to be the case.

然而,我得到了打印出来的期望,因为 methodB 的定义被执行了。我的理解是使用 spyTemp 会模拟 methodB 的定义。然而,情况似乎并非如此。

Can someone please explain where I am going wrong?

有人可以解释一下我哪里出错了吗?

采纳答案by Konstantin Labun

First issue is that you have to use spyTest object to expect something from Mockito. Here it is not the same as test. spyTempis an wrapped by Mockito object temp.

第一个问题是你必须使用 spyTest 对象来期待 Mockito 的一些东西。在这里它与测试不同。spyTemp是一个由 Mockito 包装的对象temp

Another issue is that you stub only methodB(), but trying to run methodA(). Yes in your implementation of methodA()you call methodB(), but you call at this.methodB(), not as spyTemp.methodB(). Here you have to understand that mocking would work only when you call it on the instance of temp. It's wrapped by Mockito proxy which catch your call and if you have overriden some method it would call your new implementation instead of original. But since original method called, inside it you know nothing about Mockito proxy. So your "overriden" method would be called only when you run spyTemp.methodB()

另一个问题是您只是存根methodB(),但试图运行methodA()。是的,在您methodA()调用 methodB() 的实现中,您调用的是 at this.methodB(),而不是 as spyTemp.methodB()。在这里你必须明白,只有当你在temp. 它由 Mockito 代理包装,它会捕获您的调用,如果您覆盖了某些方法,它将调用您的新实现而不是原始实现。但是由于调用了原始方法,因此在其中您对 Mockito 代理一无所知。所以你的“覆盖”方法只会在你运行时被调用spyTemp.methodB()

This should work:

这应该有效:

Mockito.doReturn(true).when(spyTemp).methodB(Mockito.any()); 
boolean status = spyTemp.methodB("XYZ");

回答by CoronA

You created a spy and mocked methodB(). That is correct! But you called methodA()on the original object. To get the correct result call it on the spy

您创建了一个间谍并嘲笑了methodB(). 那是正确的!但是你调用methodA()了原始对象。要获得正确的结果,请在 spy 上调用它

boolean status = spyTemp.methodA("XYZ");

回答by sprinter

Note the following from Mockito documentation:

请注意 Mockito 文档中的以下内容:

Mockito does notdelegate calls to the passed real instance, instead it actually creates a copy of it. So if you keep the real instance and interact with it, don't expect the spied to be aware of those interaction and their effect on real instance state. The corollary is that when an unstubbedmethod is called on the spybut not on the real instance, you won't see any effects on the real instance.

Mockito不会将调用委托给传递的真实实例,而是实际创建它的副本。因此,如果您保留真实实例并与之交互,则不要指望被监视的人会知道这些交互及其对真实实例状态的影响。推论是,当在 spy不是在真实实例上调用unstubbed方法时,您将看不到对真实实例的任何影响。

This is referring specifically to your situation. You keep a reference to tempand then call its methodA. Mockito is not spying on that instance at all; it's spying on spyTemp. So the normal methodBis called.

这是特指你的情况。您保留对的引用temp,然后调用它的methodA. Mockito 根本没有监视那个实例;它在监视spyTemp。所以methodB调用法线。

Note that you should avoid partial mocks altogether for new code.

请注意,您应该完全避免对新代码进行部分模拟。