老蒋的知识库

  • 首页
  • 文章归档
  • 关于页面

  • 搜索

Mockito与MockMvc使用技巧

发表于 2023-09-02 | 分类于 Java | 0 | 阅读次数 54

前言注意

Testng和Junit在使用过程中有所区别请参考:《Testng与Junit使用区别》

Mock的作用

构造假的关联依赖,专注测试单一服务。
假设:A有关联依赖B、C,而B、C又分别依赖D、E、F。测试A就需要将B、C、D、E、F同时构建,比较费劲。
image-1693653427737
此时我们构造一个假的B、C给到A进行使用,就会很方便我们单独测试A的功能。
image-1693653444994

Mockito

简单原理介绍

使用代理模式将原有对象再包一层。

能力

  1. 针对Spring bean对象进行Mock处理。

    • @Mock 定义一个新的Mock对象,此时不会替换Spring容器中的Bean。需要针对性打桩,未打桩方法不可调用。
    • @MockBean 替换Spring容器中的Bean。
    • @Spy 在原有的对象上进行方法层面的Mock。未打桩重新定义的方法会使用原有对象的方法。
    • @SpyBean 再原有的Bean对象上覆盖原有的方法。
  2. 打桩,针对特定的调用方式返回特定的值(或报错等其他操作)。

    • 语法:when(testDao.getRank()).thenReturn("1"),如果 testDao 调用 getRank() 就返回 1。

代码示例

@Slf4j
// testng需要添加次注解才能使用 Mockito
@TestExecutionListeners(MockitoTestExecutionListener.class)
// testng使用Spring进行Bean注入需要添加注解 @SpringBootTest,并继承 AbstractTestNGSpringContextTests
@SpringBootTest
public class TestngTest extends AbstractTestNGSpringContextTests {
    // 通过MockBean会将Spring容器内的Bean替换掉
    @MockBean
    private RankDao rankDao;

    // douyinGameRankServiceMock 构建时会依赖 rankDao
    @Autowired
    private DouyinGameRankService douyinGameRankServiceMock;

    @Test(groups = "demo")
    public void testMockito() {
        Rank rank = new Rank();
        rank.setId(1L);
        rank.setLiveUserName("测试user");
        rank.setRoomId("测试roomId");
        Mockito.when(rankDao.getRank(1L)).thenReturn(rank);

        // douyinGameRankServiceMock.getRank() 会调用rankDao.getRank(),此时会返回上面自定义的rank。
        log.debug(String.valueOf(douyinGameRankServiceMock.getRank(1L)));
    }
}

MockMvc与Mockito结合使用

MockMvc能力

基于RESTful风格的SpringMVC单元测试,可以测试完整的SpringMVC流程

代码示例

@Slf4j
// 通过注解确认需要使用 MockMvc
@AutoConfigureMockMvc
@TestExecutionListeners(MockitoTestExecutionListener.class)
@SpringBootTest(classes = GameApplication.class)
public class DouyinGameControllerTest extends AbstractTestNGSpringContextTests {

    // 通过注解注入 mockMvc
    @Autowired
    private MockMvc mockMvc;

    // 通过MockBean会将Spring容器内的Bean替换掉
    @MockBean
    private RankDao rankDao;


    @Test(groups = {"controller"})
    public void testGetRank() throws Exception {

        Rank rank = new Rank();
        rank.setId(1L);
        rank.setLiveUserName("测试user");
        rank.setRoomId("测试roomId");
        Mockito.when(rankDao.getRank(1L)).thenReturn(rank);

        List<Rank> list = new ArrayList<>();
        list.add(rank);
        Mockito.when(rankDao.getRankList()).thenReturn(list);

        // 路由 /douyin/rank 会调用rankDao.getRankList() 查询Rank列表信息,由于之前已经Mock返回值,此时的接口返回结果就是变量list中数据。
        MvcResult authResult = mockMvc.perform(MockMvcRequestBuilders.get("/douyin/rank")	// 调用get接口
                        .contentType(MediaType.APPLICATION_FORM_URLENCODED))  // 请求数据类型
                .andExpect(MockMvcResultMatchers.status().isOk()) // 验证成功响应
                .andReturn();
        authResult.getResponse().setCharacterEncoding("UTF-8"); // 设置响应解码格式
        log.debug(authResult.getResponse().getContentAsString());

    }
}
  • 本文作者: jagger
  • 本文链接: /archives/mockito与mockmvc使用技巧
  • 版权声明: 本博客所有文章除特别声明外,均采用CC BY-NC-SA 3.0 许可协议。转载请注明出处!
Testng 与 Junit 5使用中的区别
ETCD 中的坑
jagger

jagger

66 日志
31 分类
0 标签
Creative Commons
0%
© 2026 jagger
由 Halo 强力驱动