前言

在之前进行用户认证单元测试的时候,应用的是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掉的办法来进行单元测试,才明确原来单元测试应用始终不对!