优秀的编程知识分享平台

网站首页 > 技术文章 正文

单元测试 Mock 哪家强?(单元测试是模块测试吗)

nanyue 2024-10-17 11:14:32 技术文章 7 ℃

一个软件或者一个应用的开发过程中,一定是离不开单元测试的,通过单元测试可以按我们的预期验证代码是否正确。

应用实际运行时,会涉及到与数据库的交互、调用其他服务的 HTTP API,但是单元测试时,是不会真实有这些交互的,这个时候就需要通过 Mock,将与外部交互的逻辑模拟成本地自己指定的结果。

Mock 的中文译为仿制的,模拟的,虚假的。对于测试框架来说,即构造出一个模拟/虚假的对象,使我们的测试能顺利进行下去。本文我们对比一下几种 Mock 方法。

Mockito 是一种用于 Java 编程语言的开源单元测试框架,用于 mock 对象的行为,帮助单元测试,它是一个非常流行的单元测试框架,广泛用于 Java 开发,特别适用于 TDD 或 BDD 开发。

Mockito.mock() 方法

Mockito.mock() 方法允许我们创建类或接口的mock对象。

然后,我们可以使用mock来存根其方法的返回值,并验证它们是否被调用。

代码示例:

@Test
public void givenCountMethodMocked_WhenCountInvoked_ThenMockedValueReturned() {
    UserRepository localMockRepository = Mockito.mock(UserRepository.class);
    Mockito.when(localMockRepository.count()).thenReturn(111L);

    long userCount = localMockRepository.count();

    Assert.assertEquals(111L, userCount);
    Mockito.verify(localMockRepository).count();
}

在使用这个方法前,我们不需要对它做任何其他操作,直接使用即可。我们可以使用它来创建 mock 类字段,以及方法中做本地 mock。

Mockito @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,因为字段的名称显示在故障消息中。

而与 @InjectMocks 结合使用时,可以减少设置相关代码量。

Spring Boot 的 @MockBean 注解

我们可以使用 @MockBean 将 mock 对象添加到 Spring 应用程序上下文中。mock 将替换应用程序上下文中任何现有的相同类型的 bean。

如果没有定义相同类型的bean,那么将添加一个新的 bean。这个注释在集成测试中很有用,因为集成测试需要模拟特定的 bean,比如外部服务。

要使用这个注解,我们必须使用 SpringRunner 来运行测试:

@RunWith(SpringRunner.class)
public class MockBeanAnnotationIntegrationTest {
    
    @MockBean
    UserRepository mockRepository;
    
    @Autowired
    ApplicationContext context;
    
    @Test
    public void givenCountMethodMocked_WhenCountInvoked_ThenMockValueReturned() {
        Mockito.when(mockRepository.count()).thenReturn(123L);

        UserRepository userRepoFromContext = context.getBean(UserRepository.class);
        long userCount = userRepoFromContext.count();

        Assert.assertEquals(123L, userCount);
        Mockito.verify(mockRepository).count();
    }
}

小结

本文介绍了三种常见的 Mock 方法,如果你的项目是 Spring Boot,使用 @MockBean 注解是不二的选择,要不然选择 Mockito 一定不会错。

Tags:

最近发表
标签列表