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

相关推荐
java小吕布1 小时前
Java中的排序算法:探索与比较
java·后端·算法·排序算法
Goboy1 小时前
工欲善其事,必先利其器;小白入门Hadoop必备过程
后端·程序员
李少兄2 小时前
解决 Spring Boot 中 `Ambiguous mapping. Cannot map ‘xxxController‘ method` 错误
java·spring boot·后端
荆州克莱2 小时前
Big Data for AI实践:面向AI大模型开发和应用的大规模数据处理套件
spring boot·spring·spring cloud·css3·技术
代码小鑫2 小时前
A031-基于SpringBoot的健身房管理系统设计与实现
java·开发语言·数据库·spring boot·后端
Json____2 小时前
学法减分交管12123模拟练习小程序源码前端和后端和搭建教程
前端·后端·学习·小程序·uni-app·学法减分·驾考题库
monkey_meng2 小时前
【Rust类型驱动开发 Type Driven Development】
开发语言·后端·rust
落落落sss3 小时前
MQ集群
java·服务器·开发语言·后端·elasticsearch·adb·ruby
大鲤余3 小时前
Rust,删除cargo安装的可执行文件
开发语言·后端·rust
她说彩礼65万3 小时前
Asp.NET Core Mvc中一个视图怎么设置多个强数据类型
后端·asp.net·mvc