Mockito无法模拟调用

4

我将要测试的一个功能是ssh到一台机器上。我想要模拟ping方法,实际上是尝试ssh到一台机器上,因为我并没有真正地ssh到一台机器上。

我要测试的类:

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;
    }
}

测试类大致如下所示:
public class TestClass {
    public void setUp() {
        TestMachine tester = spy(new TestMachine());
    }

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

问题在于当我在本地运行它们时,它们能够正常工作,但是在我们的自动构建系统上,似乎它实际上调用了真正的ping并获得了身份验证异常。 我将使用mock()而不是spy(),因为我读到它有点奇怪,但我就是不明白为什么会有差异,它为什么会实际调用该方法!只是想知道是否还有其他人有任何见解。

好的,我已经添加了模拟对象而不是间谍对象,但是还没有通过自动构建运行它,因为现在在ping方法中出现了NPE(它依赖于一些私有变量,由于被模拟了,我无法设置这些变量),这就是最初我使用间谍对象的原因。有没有什么方法可以在不进行大量代码重构的情况下解决这个问题,或者这是我的唯一选择? - Th3sandm4n
3个回答

3

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

这告诉我们,您应该将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


3

当您使用Mockito.spy()时,对于非void方法,请使用Mockito.doReturn(),对于void方法,请使用Mockito.doNothing()。

在您的情况下:

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"));
    }
}

2
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"));
     }
} 

唯一的问题是在ping中它使用了一些私有变量(因为该类被模拟,所以这些变量没有实例化)。看起来我只能重新构造代码,使其更易于测试。 - Th3sandm4n

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接