Spring Boot Mockito (三)

Spring Boot Mockito (三)

这篇文章主要是讲解Spring boot 与 Mockito 集成测试。

前期项目配置及依赖可以查看

Spring Boot Mockito (二) - @DataJpaTest
Spring Boot Mockito (一) - @WebMvcTest

java 复制代码
@Tag("Integration")
@SpringBootTest
// @TestMethodOrder(MethodOrderer.OrderAnnotation.class)
class SpringBootMockitoApplicationTests {

    @Autowired
    OrderController orderController;
    @Autowired
    OrderRepository orderRepository;
    @Autowired
    OrderService orderService;
    @Autowired
    ObjectMapper objectMapper;
    @Autowired
    WebApplicationContext wac;
    MockMvc mockMvc;

    @BeforeEach
    void 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)
    @Test
    void 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)
    @Test
    void 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)
    @Test
    void 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)
    @Test
    void 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)
    @Test
    void 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)
    @Test
    void 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)
    @Test
    void 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

java 复制代码
package pr.iceworld.fernando.springbootmockito.bootstrap;

// ...

@Component
@RequiredArgsConstructor
public class InitData implements CommandLineRunner {
	// ...
}

增加注解@AutoConfigureMockMvc 顾名思义 - 自动化配置 mockMvc, 如以下部分

java 复制代码
/**
 * 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 {
	// ...
}
java 复制代码
@Tag("Integration")
@SpringBootTest
// @TestMethodOrder(MethodOrderer.OrderAnnotation.class)
@AutoConfigureMockMvc
class SpringBootMockitoApplicationTests {
	// ...
    // @Autowired
    // WebApplicationContext wac;
    
    @Autowired
    MockMvc mockMvc;

    @BeforeEach
    void 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层,@DataJpaTest用于测试持久层。
@DataJdbcTest - 与 @DataJpaTest功能类似

相关源码已上传到github

相关推荐
程序员良许19 分钟前
三极管推挽输出电路分析
后端·嵌入式
Java水解25 分钟前
【JAVA 进阶】Spring AOP核心原理:JDK与CGLib动态代理实战解析
后端·spring
Java水解29 分钟前
Spring Boot 4 升级指南:告别RestTemplate,拥抱现代HTTP客户端
spring boot·后端
宫水三叶的刷题日记32 分钟前
工商银行今年的年终奖。。
后端
大黄评测36 分钟前
双库协同,各取所长:.NET Core 中 PostgreSQL 与 SQLite 的优雅融合实战
后端
神云瑟瑟36 分钟前
spring boot拦截器获取requestBody的最佳实践
spring boot·拦截器·requestbody
Java编程爱好者37 分钟前
Java 后端定时任务怎么选:@Scheduled、Quartz 还是 XXL-Job?
后端
Java编程爱好者38 分钟前
线程池用完不Shutdown,CPU和内存都快哭了
后端
神奇小汤圆1 小时前
Unsafe魔法类深度解析:Java底层操作的终极指南
后端
暮色妖娆丶1 小时前
Spring 源码分析 BeanFactoryPostProcessor
spring boot·spring·源码