行为驱动开发(BDD)测试样式围绕测试的“给定”,“何时”和“然后”阶段进行。但是,古典Mockito在“给定”阶段使用“何时”一词,并且不包括可以包含BDD的其他自然语言构造。因此,在1.8.0版中引入了BDDMockito别名,以便于进行行为驱动的测试。
最常见的情况是存根方法的返回值。在以下示例中,如果使用等于的参数调用getStudent(String),则嘲笑的方法StudentRepository将返回。new Student(givenName, givenScore)givenName
import static org.mockito.BDDMockito.*; public class ScoreServiceTest { private StudentRepository studentRepository = mock(StudentRepository.class); private ScoreService objectUnderTest = new ScoreService(studentRepository); @Test public void shouldCalculateAndReturnScore() throws Exception { //given String givenName = "Johnny"; int givenScore = 10; given(studentRepository.getStudent(givenName)) .willReturn(new Student(givenName, givenScore)); //when String actualScore = objectUnderTest.calculateStudentScore(givenName); //then assertEquals(givenScore, actualScore); } }
有时需要检查从依赖关系抛出的异常是否在被测试方法中得到了正确处理或重新抛出。这样的行为可以通过以下方式在“给定”阶段中消除:
willThrow(new RuntimeException())).given(mock).getData();
有时,需要设置一些存根方法应该引入的副作用。特别是在以下情况下可以派上用场:
存根方法是一种应该更改传递对象内部状态的方法
存根方法是空方法
可以在“给定”阶段使用“答案”来纠正此类行为:
willAnswer(invocation -> this.prepareData(invocation.getArguments()[0])).given(mock).processData();
当需要验证与模拟的交互时,可以使用should()或should(VerificationMode)(仅从1.10.5开始)方法在“然后”阶段中完成:
then(mock).should().getData(); // 验证一次getData()被调用 then(mock).should(times(2)).processData(); // 验证是否两次调用了processData()
当需要验证除了已验证之外,没有其他与模拟的交互时,可以在“然后”阶段使用shouldHaveNoMoreInteractions()(自2.0.0开始):
then(mock).shouldHaveNoMoreInteractions(); // 经典Mockito中verifyVerMoreInteractions(mock)的类似物
当需要验证与某个模拟绝对没有交互时,可以在“然后”阶段使用shouldHaveNoMoreInteractions()(自2.0.0开始)完成:
then(mock).shouldHaveZeroInteractions(); // 经典Mockito中verifyZeroInteractions(mock)的类似物
当需要检查是否按顺序调用了方法时,可以在“然后”阶段使用should(InOrder)(自1.10.5起)和should(InOrder, VerificationMode)(自2.0.0起)进行操作:
InOrder inOrder = inOrder(mock); // 在这里测试身体 then(mock).should(inOrder).getData(); // 模拟的第一次调用应该是getData()调用 then(mock).should(inOrder, times(2)).processData(); // 模拟中的第二个和第三个调用应该是processData()调用