java Mockito 不是在嘲笑电话

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

Mockito is not mocking a call

javaunit-testingmockingmockito

提问by Th3sandm4n

One of the functions I'm testing is sshing into a machine. I want to mock the ping method, that actually tries to ssh into a machine, since I am not really sshing into a machine.

我正在测试的功能之一是 SSH 到一台机器。我想模拟 ping 方法,该方法实际上试图通过 ssh 进入机器,因为我并没有真正进入机器。

class I am testing:

我正在测试的课程:

public class TestMachine {
    public int ping(host){
    }

    public boolean machineIsGood(host) {
        blah blah
        int val = ping(host);
        blah blah blah
        if(val != 0) return false;
        return true;
    }
}

The test class goes something like this:

测试类是这样的:

public class TestClass {
    public void setUp() {
        TestMachine tester = spy(new TestMachine());
    }

    public void testOne() {
         when(test.ping(anyString()).thenReturn(-1);
         assertFalse(tester.machineIsGood("testHost"));
    }
{

The problem is that when I am running them locally, they work just fine, but on our autobuild system it seems like it is actually calling the real ping and getting an Authentication Exception. I'm going to use mock() instead of spy() since I've read it's a bit weird, but I just can't understand what makes a difference in that it is actually calling the method! Just wondering if anyone else has any insight.

问题是,当我在本地运行它们时,它们工作得很好,但在我们的自动构建系统上,它似乎实际上是在调用真正的 ping 并获得身份验证异常。我将使用 mock() 而不是 spy() 因为我读过它有点奇怪,但我无法理解它实际上是在调用方法有什么不同!只是想知道是否有人有任何见解。

采纳答案by esmiralha

public class TestClass {
  private TestMachine tester;
  public void setUp() {         
    tester = mock(TestMachine.class);     
  }      

  public void testOne() {
          when(tester.ping(anyString()).thenReturn(-1);
          assertFalse(tester.machineIsGood("testHost"));
     }
} 

回答by Thomas Dufour

In my experience, you should not use mocks to test interactions between methods in the same class.

根据我的经验,您不应该使用模拟来测试同一类中方法之间的交互。

What this tells us is that you should decouple your SUT (system under test) from the external dependency that you need to replace with a test double (the ping that you do not want to call "for real" in your unit tests).

这告诉我们的是,您应该将 SUT(被测系统)与需要替换为测试替身(您不想在单元测试中“真正”调用的 ping)的外部依赖项分离。


public class Pinger {
    public int ping(String host) {
        // yadda yadda
    }
}

public class TestMachine {

    private final Pinger pinger;

    public TestMachine(final Pinger pinger) {
        this.pinger = pinger;
    }

    public boolean machineIsGood(host) {
        // blah blah
        int val = pinger.ping(host);
        // blah blah blah
        return val == 0;
    }
}

public class TestMachineTest {
    @Test
    public void testOne() {
        final Pinger pinger = mock(Pinger.class);
        when(pinger.ping(anyString())).thenReturn(-1);

        TestMachine tester = new TestMachine(pinger);
        assertFalse(tester.machineIsGood("testHost"));
    }
}

HTH

HTH

回答by Tarek

When you use Mockito.spy(), use the Mockito.doReturn() for non-void methods or Mockito.doNothing() for void methods.

当您使用 Mockito.spy() 时,将 Mockito.doReturn() 用于非空方法或 Mockito.doNothing() 用于空方法。

In your case:

在你的情况下:

public class TestClass {
    public void setUp() {
        TestMachine tester = Mockito.spy(new TestMachine());
    }

    public void testOne() {
        doReturn(-1).when(test).ping(Mockito.anyString())
        assertFalse(tester.machineIsGood("testHost"));
    }
}