可变输出Mockito嘲笑

4 java unit-testing mocking mockito

我有一个WidgetProcessor依赖于另一个类的类,FizzChecker:

public class FizzChecker {
    public boolean hasMoreBuzz() {
        // Sometimes returns true, sometimes returns false.
    }
}
Run Code Online (Sandbox Code Playgroud)

hasMoreBuzz()从内部调用此方法,WidgetProcessor如下所示:

public class WidgetProcessor {
    public int process() {
        while(fizzChecker.hasMoreBuzz()) {
            // ... process stuff in here
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我想在以下时间编写测试用例:

  • fizzChecker.hasMoreBuzz() 第一次调用时返回false(因此循环永远不会执行)
  • fizzChecker.hasMoreBuzz() 在第5次调用时返回false

我正在试图弄清楚如何用Mockito来实现这一目标.到目前为止,我最好的(可怕的)尝试:

WidgetProcessor fixture = new WidgetProcessor();
FizzChecker mockFizzChecker = Mockito.mock(FizzChecker.class);

// This works great for the first test case, but what about the 2nd
// where I need it to return: true, true, true, true, false?
Mockito.when(mockFizzChecker).hasMoreBuzz().thenReturn(false);

fixture.setFizzChecker(mockFizzCheck);

fixture.process();

// Assert omitted for brevity
Run Code Online (Sandbox Code Playgroud)

提前致谢.

Jef*_*ica 7

您可以传递多个值thenReturn,或保持链接.对stubbed方法的连续调用将按顺序返回操作,重复所有调用的最终操作.例子:

// will return true four times, and then false for all calls afterwards
when(mockFizzChecker.hasMoreBuzz()).thenReturn(true, true, true, true, false);
when(mockFizzChecker.hasMoreBuzz())
    .thenReturn(true)
    .thenReturn(true)
    .thenReturn(true)
    .thenReturn(true)
    .thenReturn(false);
// you can also switch actions like this:
when(someOtherMock.someMethodCall())
    .thenReturn(1, 2)
    .thenThrow(new RuntimeException());
Run Code Online (Sandbox Code Playgroud)

您可能希望单独设置它们:

public class WidgetProcessorTest {
  private WidgetProcessor processor;
  private FizzChecker mockFizzChecker;

  @Before public void setUp() {
    processor = new WidgetProcessor();
    mockFizzChecker = Mockito.mock(FizzChecker.class);
    processor.setFizzChecker(mockFizzChecker);
  }

  @Test public void neverHasBuzz() {
    when(mockFizzChecker.hasMoreBuzz()).thenReturn(false);
    processor.process();
    // asserts
  }

  @Test public void hasFiveBuzzes() {
    when(mockFizzChecker.hasMoreBuzz())
        .thenReturn(true, true, true, true, false);
    processor.process();
    // asserts
  }
}
Run Code Online (Sandbox Code Playgroud)

最后一点:实际上,您可能会发现需要协调多个呼叫(例如hasMoreBuzzgetNextBuzz).如果它开始变得复杂,你可以预见在很多测试中写这个,考虑跳过Mockito,而只是实现一个FakeFizzChecker.