乐趣区

关于springboot:近期学习总结

前言

在之前进行用户认证单元测试的时候,应用的是 RestTemplate 来模仿发动申请,然而平时用的更多的是 MockMvc 来进行后盾的申请。他们两个有何不同呢?

RestTemplate

部署的一个实在的 web 服务器来监听 http 申请,响应后果
既然是实在的,那么它最大的弊病就是无奈进行事物回滚:

在测试完结后,发现并没有对数据进行回滚,然而我在认证单元测试的时候并没有波及到数据库回滚的问题,所以跟 mockmvc 没有区别
起因:@Transactional 注解对于 RestTemplate 是生效的,所以不会进行事物回滚

MockMvc

mockmvc 通常是通过设置一个残缺的高低完应用程序来模仿 HTTP 申请和响应
创立的是一个假的 DispatcherServlet 来模仿 MVC 堆栈的运行,并没有真正的网络链接

既然是模仿的,那么咱们能够通过注解 @Transactional 来进行事务的回滚,并不会因为测试对数据库造成副作用。

总结

综上:在更多时候进行单元测试的时候咱们还是应该偏向于 MockMvc 的,然而当有非凡需要的时候,咱们能够应用 RestTemplate。

单元测试遇到的问题:

问题一:

仿照之前老我的项目写 update 的单元测试代码:

@Test
  void update() throws Exception {Long id = new Random().nextLong();
    Town oldTown = getOneTown();
    oldTown.setId(id);
    Town newTown = getOneTown();
    String jsonString = JSON.toJSONString(oldTown);

    String url = baseUrl + "/" + id.toString();

    Mockito.doReturn(newTown).when(this.townService).update(id, oldTown);

    MockHttpServletRequestBuilder putRequest = MockMvcRequestBuilders
            .put(url)
            .contentType(MediaType.APPLICATION_JSON)
            .content(jsonString);

    this.mockMvc.perform(putRequest)
            .andExpect(MockMvcResultMatchers.jsonPath("$.id").value(newTown.getId()))
            .andExpect(MockMvcResultMatchers.jsonPath("$.name").exists())
            .andExpect(MockMvcResultMatchers.jsonPath("$.pinyin").exists())
            .andExpect(status().isOk());

    ArgumentCaptor<Town> townArgumentCaptor = ArgumentCaptor.forClass(Town.class);
    ArgumentCaptor<Long> longArgumentCaptor = ArgumentCaptor.forClass(Long.class);
    Mockito.verify(this.townService).update(longArgumentCaptor.capture(),
            townArgumentCaptor.capture());
    org.assertj.core.api.Assertions.assertThat(longArgumentCaptor.getValue()).isEqualTo(id);
    org.assertj.core.api.Assertions.assertThat(townArgumentCaptor.getValue().getName()).isEqualTo(oldTown.getName());
  }


首先是谬误翻译:返回值的 id 属性不存在

排查:

1. 第一反馈认为是我 C 层 Long 属性写成 Integer 类型了

2. 查看响应状态:passed,申请胜利

3. 猜想返回值出了问题,因为申请是没有问题的:

认真想了之后:oldTown 在模仿发动申请的时候,传入的 oldTown 与 mock 中的 oldTown 就不是一个对象了,那他必然不会返回 newTown!

总结

还是对于单元测试短少锤炼,还须要通过一直的写来加深了解。

问题二:

依据 id 获取对象 c 层测试:

@Test
  void getById() throws Exception{Town town = getOneTown();

    Mockito.doReturn(town).when(this.townService).getById(Mockito.eq(town.getId()));

    String url = baseUrl + "/" + town.getId().toString();

    this.mockMvc.perform(MockMvcRequestBuilders.get(url))
            .andExpect(MockMvcResultMatchers.status().isOk());
  }

与历史我的项目比照,找区别:

将至改为 Long 便能够胜利拜访了!

认为是本人的申请的为 Long 类型,然而想到转换了 String 类型了啊,跟 Integer 一样啊

改为 Integer 测试还是不行!

总结

单元测试应用还是不够纯熟,应用办法也不对,总是在都写完之后进行集成测试,在明天老师讲了能够将未实现的办法间接 mock 掉的办法来进行单元测试,才明确原来单元测试应用始终不对!

退出移动版