Spring Boot Mockito (三)
这篇文章主要是讲解Spring boot 与 Mockito 集成测试。
前期项目配置及依赖可以查看
Spring Boot Mockito (二) - @DataJpaTest
Spring Boot Mockito (一) - @WebMvcTest
@Tag("Integration")
@SpringBootTest
// @TestMethodOrder(MethodOrderer.OrderAnnotation.class)
class SpringBootMockitoApplicationTests {@AutowiredOrderController orderController;@AutowiredOrderRepository orderRepository;@AutowiredOrderService orderService;@AutowiredObjectMapper objectMapper;@AutowiredWebApplicationContext wac;MockMvc mockMvc;@BeforeEachvoid setUp() {mockMvc = MockMvcBuilders.webAppContextSetup(wac).build();}@Test@org.junit.jupiter.api.Order(1)void test_ListAllOrders() throws Exception {long count = orderRepository.count();ResultActions resultActions = mockMvc.perform(get(ORDER_PATH)).andExpect(status().isOk());resultActions.andExpect(jsonPath("$.size()").value(count));//System.out.println(resultActions.andReturn().getResponse().getContentAsString(Charset.forName("UTF-8")));}@org.junit.jupiter.api.Order(2)@Testvoid test_GetOrderById() throws Exception {Order order = orderRepository.findAll().get(0);ResultActions resultActions = mockMvc.perform(get(ORDER_PATH + "/{id}", order.getId())).andExpect(status().isOk());resultActions.andExpect(jsonPath("$.id").value(order.getId())).andExpect(jsonPath("$.name").value(order.getName())).andExpect(jsonPath("$.price").value(order.getPrice()));}@org.junit.jupiter.api.Order(3)@Testvoid test_GetOrderById_404() throws Exception {Long orderId = orderRepository.findAll().stream().mapToLong(e -> e.getId()).max().orElse(0) + 10;ResultActions resultActions = mockMvc.perform(get(ORDER_PATH + "/{id}", orderId)).andExpect(status().isNotFound());}@org.junit.jupiter.api.Order(4)@Testvoid test_UpdateOrderById() throws Exception {Order order = orderRepository.findAll().get(0);Order updatedOrder = order;updatedOrder.setName("Picnic pot");updatedOrder.setPrice(95.5d);mockMvc.perform(put(ORDER_PATH + "/{id}", order.getId()).accept(MediaType.APPLICATION_JSON).contentType(MediaType.APPLICATION_JSON).content(objectMapper.writeValueAsString(updatedOrder))).andExpect(status().isNoContent());order = orderRepository.findById(order.getId()).get();assertEquals(order.getId(), updatedOrder.getId());assertEquals(order.getName(), updatedOrder.getName());assertEquals(order.getPrice(), updatedOrder.getPrice());}@org.junit.jupiter.api.Order(5)@Testvoid test_UpdateOrderById_404() throws Exception {Order order = orderRepository.findAll().get(0);Long orderId = orderRepository.findAll().stream().mapToLong(e -> e.getId()).max().orElse(0) + 10;Order updatedOrder = order;updatedOrder.setId(orderId + 10);updatedOrder.setName("Picnic pot");updatedOrder.setPrice(95.5d);mockMvc.perform(put(ORDER_PATH + "/{id}", updatedOrder.getId()).accept(MediaType.APPLICATION_JSON).contentType(MediaType.APPLICATION_JSON).content(objectMapper.writeValueAsString(updatedOrder))).andExpect(status().isNotFound());}@org.junit.jupiter.api.Order(6)@Testvoid test_CreateNewOrder() throws Exception {Order order = Order.builder().name("Picnic pot").price(95.5d).build();ResultActions resultActions = mockMvc.perform(post(ORDER_PATH).accept(MediaType.APPLICATION_JSON).contentType(MediaType.APPLICATION_JSON).content(objectMapper.writeValueAsString(order))).andExpect(status().isCreated());Order createdOrder = objectMapper.readValue(resultActions.andReturn().getResponse().getContentAsString(), Order.class);order = orderRepository.findById(createdOrder.getId()).get();assertNotNull(order);}@org.junit.jupiter.api.Order(7)@Testvoid test_DeleteOrderById() throws Exception {Order order = orderRepository.findAll().get(0);mockMvc.perform(delete(ORDER_PATH + "/{id}", order.getId())).andExpect(status().isNoContent());Optional<Order> existed = orderRepository.findById(order.getId());assertFalse(existed.isPresent());}@org.junit.jupiter.api.Order(8)@Testvoid test_DeleteOrderById_404() throws Exception {Long orderId = orderRepository.findAll().stream().mapToLong(e -> e.getId()).max().orElse(0) + 10;mockMvc.perform(delete(ORDER_PATH + "/{id}", orderId)).andExpect(status().isNotFound());}
}
@org.junit.jupiter.api.Order
在这里没有起作用是由于已注释了@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
将 InitData
类 移入到了测试文件夹中,SpringBootApplication主类启动不会加载InitData
类
package pr.iceworld.fernando.springbootmockito.bootstrap;// ...@Component
@RequiredArgsConstructor
public class InitData implements CommandLineRunner {// ...
}
增加注解@AutoConfigureMockMvc
顾名思义 - 自动化配置 mockMvc
, 如以下部分
/*** Annotation that can be applied to a test class to enable and configure* auto-configuration of {@link MockMvc}.* ...*/@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@ImportAutoConfiguration
@PropertyMapping("spring.test.mockmvc")
public @interface AutoConfigureMockMvc {// ...
}
@Tag("Integration")
@SpringBootTest
// @TestMethodOrder(MethodOrderer.OrderAnnotation.class)
@AutoConfigureMockMvc
class SpringBootMockitoApplicationTests {// ...// @Autowired// WebApplicationContext wac;@AutowiredMockMvc mockMvc;@BeforeEachvoid setUp() {// mockMvc = MockMvcBuilders.webAppContextSetup(wac).build();}// ...
}
@SpringBootTest
- Spring Boot为集成测试提供了@SpringBootTest
注释。此注释创建应用程序上下文并加载完整的应用程序上下文。
@WebMvcTest
- SpringBoot提供@WebMvcTest
注释来测试Spring MVC控制器。基于@WebMvcTest的测试运行得更快,因为它只加载指定的控制器及其依赖项,而不加载整个应用程序。
Spring Boot只实例化web层,而不是整个应用程序上下文。在具有多个控制器的应用程序中,还可以通过使用@WebMvcTest(TestControllerOnly.class)
来仅实例化一个控制器。
@DataJpaTest
- 就像@WebMvcTest
可以测试web层,@DataJpaTes
t用于测试持久层。
@DataJdbcTest
- 与 @DataJpaTest
功能类似
相关源码已上传到github