Mockito.mock
mock()方法可以创建类或接口的模拟对象。
我们可以使用mock来指定方法的行为,并验证它们是否被调用。
举个例子:
@Testpublic void givenCountMethodMocked_WhenCountInvoked_ThenMockedValueReturned() { //mock对象 UserRepository localMockRepository = Mockito.mock(UserRepository.class); //指定mock对象的行为 Mockito.when(localMockRepository.count()).thenReturn(0L); //调用mock对象 long userCount = localMockRepository.count(); Assert.assertEquals(0L, userCount); //验证localMockRepository的方法被调用 Mockito.verify(localMockRepository).count();}复制代码
在使用此方法之前,不需要执行任何其他操作。我们可以使用它在类中Mock字段或者在函数中Mock局部变量。
@Mock注解
Mock注解实际上是mockito.mock()方法的缩写,同样,我们应该只在测试类中使用它。
与mock()方法不同,我们需要启用mockito注解来使用此注解。我们可以通过使用mockitojunitrunner运行测试或显式调用mockitoannotations.initmocks()方法来实现这一点。
MockitoJUnitRunner
@RunWith(MockitoJUnitRunner.class)public class MockAnnotationUnitTest { @Mock UserRepository mockRepository; @Test public void givenCountMethodMocked_WhenCountInvoked_ThenMockValueReturned() { Mockito.when(mockRepository.count()).thenReturn(123L); long userCount = mockRepository.count(); Assert.assertEquals(123L, userCount); Mockito.verify(mockRepository).count(); }}复制代码
相比较mock方法,Mock注解除了使代码更易读之外,还可以在出现故障时更容易找到问题,因为在错误消息中会出现字段名称。
Wanted but not invoked:mockRepository.count();......Actually, there were zero interactions with this mock.复制代码
MockBean注解
我们可以使用@mockBean注解将Mock对象添加到Spring上下文中。
Mock将替换Spring上下文中任何相同类型的现有bean,如果没有定义相同类型的bean,将添加一个新的bean。
MockBean注解在集成测试中很有用,在集成测试中需要模拟特定bean,例如外部Service。
如果需要使用Mockbean注解,需要使用SpringRunner(Junit5 中是SpringExtention)
@RunWith(SpringRunner.class)public class MockBeanAnnotationIntegrationTest { //mock对象 @MockBean UserRepository mockRepository; @Autowired ApplicationContext context; @Test public void givenCountMethodMocked_WhenCountInvoked_ThenMockValueReturned() { //指定mock对象的行为 Mockito.when(mockRepository.count()).thenReturn(123L); //通过应用程序上下文获取Mock的对象 //也可以直接调用mockRepository.count()方法 UserRepository userRepoFromContext = context.getBean(UserRepository.class); long userCount = userRepoFromContext.count(); Assert.assertEquals(123L, userCount); //验证被调用的就是Mock的对象 Mockito.verify(mockRepository).count(); }}复制代码
可以看到,通过上下文获取的对象,正是通过mockBean注解mock的对象。