Java 可变输出Mockito mocks

Java 可变输出Mockito mocks,java,unit-testing,mocking,mockito,Java,Unit Testing,Mocking,Mockito,我有一个类WidgetProcessor,它依赖于另一个类FizzChecker: public class FizzChecker { public boolean hasMoreBuzz() { // Sometimes returns true, sometimes returns false. } } 这个hasMoreBuzz()方法是从WidgetProcessor内部调用的,如下所示: public class WidgetProcessor {

我有一个类
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()
    在第五次调用时返回false
我想知道如何用Mockito来完成这个任务。到目前为止,我最好(糟糕)的尝试是:

提前感谢。

尝试使用。这将允许您在调用hasMoreBuzz()方法时执行代码

请看上面提供的链接中的示例。如果创建一个Answer对象,并实现Answer()方法来保留计数器,则可以根据该计数器的值执行操作

编辑:我编写了一个快速测试程序来验证这一点。这是:

package com.ejk;
import org.junit.Test;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import static org.mockito.Mockito.when;
import static org.mockito.Mockito.mock;

public class SO {
    @Test
    public void testIt() {          
        IFoo mock = mock(IFoo.class);
        MyAnswer myAnswer = new MyAnswer();
        when(mock.doFoo()).then(myAnswer);
        for (int i=1; i<10; i++) {
            System.out.println(i+ ") " + mock.doFoo());
        }
    }
    class MyAnswer implements Answer<Boolean> {
        int counter = 1;
        @Override
        public Boolean answer(InvocationOnMock invocation) throws Throwable {
            return (counter++ == 5) ? Boolean.FALSE : Boolean.TRUE;
        }

    }
    interface IFoo {
        boolean doFoo();
    }
}
package com.ejk;
导入org.junit.Test;
导入org.mockito.invocation.invocationMock;
导入org.mockito.stubing.Answer;
导入静态org.mockito.mockito.when;
导入静态org.mockito.mockito.mock;
公开课{
@试验
public void testIt(){
IFoo mock=mock(IFoo.class);
MyAnswer MyAnswer=新的MyAnswer();
when(mock.doFoo())。然后(myAnswer);
对于(int i=1;i您可以。对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());
您可能需要单独设置它们:

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
  }
}
<>最后注意:在现实中,你可能发现你需要协调多个调用(比如<代码> HasMuuBuz 和<代码> GETNEXBUZZ)。如果它开始变得复杂,并且你可以预见在很多测试中写这个,考虑跳过Mokito,而只是.< /P>
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
  }
}