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

public class FizzChecker {
    public boolean hasMoreBuzz() {
        // Sometimes returns true, sometimes returns false.
    }
}

hasMoreBuzz()内部调用此WidgetProcessor方法,如下所示:
public class WidgetProcessor {
    public int process() {
        while(fizzChecker.hasMoreBuzz()) {
            // ... process stuff in here
        }
    }
}

我想在以下情况下编写测试用例:
  • 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
    

    提前致谢。

    最佳答案

    您可以pass in multiple values to thenReturn , or keep chaining。连续调用存根方法将按顺序返回操作,并为所有调用重复最终操作。例子:

    // 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());
    

    您可能需要单独设置它们:
    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
      }
    }
    

    最后注意:实际上,您可能会发现需要协调多个调用(例如hasMoreBuzzgetNextBuzz)。如果开始变得复杂,并且可以预见将在许多测试中编写此代码,请考虑跳过Mockito,而是跳过implementing a FakeFizzChecker

    08-26 21:29