单元测试 - MockBean

2021-01-20 19:39:37 浏览数 (1)

为依赖外部组件的代码做单元测试,需要使用Mockito,如果是Spring上下文的话,可以使用MockBean

测试代码示例

  • 使用原生的Bean
代码语言:javascript复制
@SpringBootTest
class TransactionManagerNoMockTest {
    @Resource
    private TransactionManager transactionManager;

    @Test
    void getUserInfo() {
        User user = transactionManager.getUserInfo(1);
        Assertions.assertEquals(1, user.getId());
        Assertions.assertEquals("name1", user.getName());
    }
}
  • 使用Mock的Bean

使用@MockBean替换Spring上下文中的Bean(这样会导致Spring上下文重启)

代码语言:javascript复制
@SpringBootTest
class TransactionManagerWithMockTest {

    /**
     * 注入Mock的UserManager,替换Spring上下文中的UserManager
     */
    @MockBean
    private UserManager userManager;

    @Resource
    private TransactionManager transactionManager;

    @BeforeEach
    public void setUp() {
        //重置Mock,防止重复设置
        Mockito.reset(userManager);
        
        //设置Mock行为
        Mockito.when(userManager.getOne(Mockito.anyInt()))
                .thenAnswer((Answer<User>) invocationOnMock -> {
                    Integer userId = invocationOnMock.getArgument(0, Integer.class);
                    return User.builder().id(userId).name(userId.toString()).build();
                });
    }

    @Test
    void getUserInfo() {
        User user = transactionManager.getUserInfo(1);
        Assertions.assertEquals(1, user.getId());
        Assertions.assertEquals("1", user.getName());
    }
}

常见错误

  • When using matchers, all arguments have to be provided by matchers. Mocktio设置的时候,如果参数有Mockito生成的,那么所有的参数都需要由Mockito生成,哪怕是常量,也要使用Mockito.eq(常量)

@Mock与@MockBean的区别

  • Mock一般用在不依赖框架的单元测试
  • MockBean用在依赖Spring上下文环境

参考

  • Springboot集成测试MockBean踩坑记录
  • Difference Between @Mock and @MockBean (Spring Boot Applications)
  • 有赞单元测试实践

0 人点赞