在测试期间伪造来自void方法调用的响应

时间:2015-12-22 13:37:19

标签: java junit mockito

我正在测试一个班级TestObject。在这个类中有一个void返回函数stageOne(String),我想测试它。在stageOne结束时,调用另一个void返回函数stageTwo(String)。我想伪造来自stageTwo的回复,以便stageTwo永远不会被调用。要通过测试TestObject,只需要调用stageTwo一次。

我使用when...thenReturn尝试了各种各样的事情,但却无法让它发挥作用。以下是我目前的最佳猜测。

class TestClass {
    private TestObject testObject;

    @Before
    public static void setUp() {
        testObject = new TestObject();
    }

    @Test
    public void test1() {
        when(testObject.stageTwo(any(String.class))).thenReturn(Void);
        testObject.stageOne("Test data");
        verify(testObject, times(1)).stageTwo(any(String.class));
    }    
}

我使用IntelliJ并且能够进行其他测试,我根本无法使when...then构造完全正常工作。在上面的示例中,IntelliJ建议我将其变为局部变量OngoingStubbing<Void> voidOngoingStubbing,然后它说这也是错误的。

我也试过了这行

doNothing().when(testObject.stageTwo(any(String.class)));

但这也不起作用。 intelliJ使用与之前相同的消息强调when()的内容。

编辑:下面的TestObject结构:

public class TestObject {

  public void stageOne(String str) {
    String str2 = ...
    // do stuff
    stageTwo(str2) // don't proceed with this method, but verify that it was called
  }

  public void stageTwo(String str) {
    // do stuff which I don't want to do in this test
    // e.g. calls to external services and other complexities
  }

}

1 个答案:

答案 0 :(得分:1)

您可以使用部分模拟,例如示例here。确保首先将对象创建为模拟。

TestObject testObject = mock(TestObject.class);
doNothing().when(testObject.stageTwo(anyString()));
when(testObject.stageOne(anyString())).thenCallRealMethod();

如果值得将代码分成两种方法,那么考虑重构代码可能会更好。例如,如果代码调用您的对象并且只运行第一个方法是合理的,那么从第一个方法中删除对stageTwo的调用,并强制调用代码来同时调用stageOnestageTwo。或者,或者,让stageOne返回它的字符串,并编写第三种方法来调用所有阶段:

public void allStages(String str) {
    String str2 = stageOne(str);
    stageTwo(str2);
}

这很好地分解了你的方法,并允许你单独测试它们。你在两种方法之间存在太多耦合的情况下设置它的方式,所以如果你真的希望它们是分开的,你应该考虑这样的事情。