Mock测试

导入依赖

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

<!--        fastjson-->
        <dependency>
            <groupId>com.alibaba.fastjson2</groupId>
            <artifactId>fastjson2</artifactId>
            <version>2.0.51</version>
        </dependency>


package com.gmgx.service.impl;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.TypeReference;
import com.gmgx.common.Result;
import com.gmgx.controller.OrdersController;
import com.gmgx.entity.Orders;
import com.gmgx.exceptions.enumeration.ResponseEnum;
import com.gmgx.vo.OrderVo;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.ResultActions;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;

import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;

@Slf4j
@SpringBootTest
@AutoConfigureMockMvc
public class OrdersControllerTests {

    @Resource
    private MockMvc mockMvc;

    @BeforeEach
    public void before() {
        log.info("携带请求头");
    }

    @Test
    public void cancelByMember_success() throws Exception {
        //参数
        Orders order = new Orders();
        order.setId("20240912694cf3e4907d4b28b40b5101");
        order.setStatus(2);
        order.setCancelReasonMember("不想要了");

        //模拟http请求
        ResultActions resultActions = mockMvc.perform(
                        put("/order/cancelByMember") //put方法 路径要写全
                                .contentType(MediaType.APPLICATION_JSON) //以json的形式传递参数
                                .content(JSON.toJSONString(order)) //用fastjson提供的方法将参数转换为json字符串
//                        .header("Authorization", token)  从beforeEach拿到token
                )
                //断言  根据下面打印的结果来写,理论上这一段是最后加
                .andExpect(MockMvcResultMatchers.jsonPath("$.code").value(ResponseEnum.SUCCESS.getCode()))
                .andExpect(MockMvcResultMatchers.jsonPath("$.msg").value(ResponseEnum.SUCCESS.getMessage()))
                .andExpect(MockMvcResultMatchers.jsonPath("$.success").value(true))
                .andExpect(MockMvcResultMatchers.jsonPath("$.data").isNotEmpty());

        //获取HTTP响应的内容,并将其作为字符串。
        String contentAsString = resultActions.andReturn().getResponse().getContentAsString();
        //反序列化json字符串,得到期望的对象(即控制器的返回类型)
        //public Result<Object> cancelByMember  这里已经确定里面的Object是String类型,就直接用Result<String>
        Result<String> result = JSON.parseObject(contentAsString, new TypeReference<Result<String>>() {
        });
        log.info(result.getData());
    }

    @Test
    public void cancelByMember_noParams() throws Exception {
        Orders order = new Orders();
        ResultActions resultActions = mockMvc.perform(
                        put("/order/cancelByMember")
                                .contentType(MediaType.APPLICATION_JSON)
                                .content(JSON.toJSONString(order))
                ).andExpect(MockMvcResultMatchers.jsonPath("$.code").value(ResponseEnum.INVALID_PARAMETERS.getCode()))
                .andExpect(MockMvcResultMatchers.jsonPath("$.msg").value(ResponseEnum.INVALID_PARAMETERS.getMessage()))
                .andExpect(MockMvcResultMatchers.jsonPath("$.success").value(false))
                .andExpect(MockMvcResultMatchers.jsonPath("$.data").value("订单id不能为空"));
        ;
        String contentAsString = resultActions.andReturn().getResponse().getContentAsString();
        Result<Object> result = JSON.parseObject(contentAsString, new TypeReference<Result<Object>>() {
        });
        log.info(result.getData().toString());
    }

    @Test
    public void getDetails_success() throws Exception {
        String oId = "20240912694cf3e4907d4b28b40b5101";
        ResultActions resultActions = mockMvc.perform(
                        get("/order/details/{oId}", oId)
                )
                .andExpect(MockMvcResultMatchers.jsonPath("$.code").value(ResponseEnum.SUCCESS.getCode()))
                .andExpect(MockMvcResultMatchers.jsonPath("$.msg").value(ResponseEnum.SUCCESS.getMessage()))
                .andExpect(MockMvcResultMatchers.jsonPath("$.success").value(true))
                .andExpect(MockMvcResultMatchers.jsonPath("$.data").isNotEmpty());


        String contentAsString = resultActions.andReturn().getResponse().getContentAsString();
        Result<OrderVo> result = JSON.parseObject(contentAsString, new TypeReference<Result<OrderVo>>() {
        });
        log.info(result.getData().toString());
    }


//    @MockBean
//    private OrdersController ordersController;
//
//    @Test
//    public void Simulate() throws Exception {
//        String oId = "20240912694cf3e4907d4b28b40b5101";
//        Result<Object> error = Result.error("模拟这个订单无法复现");
//        //但是实际上它是可以复现的
//        Mockito.when(ordersController.repetition(oId)).thenReturn(error);
//
//
//        ResultActions resultActions = mockMvc.perform(
//                        post("/order/repetition/{oId}", oId)
//                                .accept(MediaType.APPLICATION_JSON + ";charset=UTF-8")//以json的格式接收响应
//                )
//                .andExpect(MockMvcResultMatchers.jsonPath("$.code").value(ResponseEnum.UNKNOWN_ERROR.getCode()))
//                .andExpect(MockMvcResultMatchers.jsonPath("$.msg").value(ResponseEnum.UNKNOWN_ERROR.getMessage()))
//                .andExpect(MockMvcResultMatchers.jsonPath("$.success").value(false));
//    }
}


@RequestMapping("/order")
@Tag(name = "订单控制器")

@SpringBootTest
@AutoConfigureMockMvc

@Resource
private MockMvc mockMvc;

案例1


@PutMapping("cancelByMember")
public Result<Object> cancelByMember(@RequestBody @Validated(value = ValidGroup.IdAndCancelReasonMember.class) Orders order) {
    Boolean flag = ordersService.cancelByMember(order);
    if (flag) {
        return Result.success("用户取消订单成功");
    }
    return Result.error(ResponseEnum.INVALID_ORDER_STATUS_CHANGED);
}

@Test
public void cancelByMember_success() throws Exception {
//参数
Orders order = new Orders();
order.setId("20240912694cf3e4907d4b28b40b5101");
order.setStatus(2);
order.setCancelReasonMember("不想要了");

//模拟http请求
ResultActions resultActions = mockMvc.perform(
    put("/order/cancelByMember") //put方法 路径要写全
    .contentType(MediaType.APPLICATION_JSON) //以json的形式传递参数
    .content(JSON.toJSONString(order)) //用fastjson提供的方法将参数转换为json字符串
    //                        .header("Authorization", token)  从beforeEach拿到token
)
//断言  根据下面打印的结果来写,理论上这一段是最后加
.andExpect(MockMvcResultMatchers.jsonPath("$.code").value(ResponseEnum.SUCCESS.getCode()))
.andExpect(MockMvcResultMatchers.jsonPath("$.msg").value(ResponseEnum.SUCCESS.getMessage()))
.andExpect(MockMvcResultMatchers.jsonPath("$.success").value(true))
.andExpect(MockMvcResultMatchers.jsonPath("$.data").isNotEmpty());

//获取HTTP响应的内容,并将其作为字符串。
String contentAsString = resultActions.andReturn().getResponse().getContentAsString();
//反序列化json字符串,得到期望的对象(即控制器的返回类型)
//public Result<Object> cancelByMember  这里已经确定里面的Object是String类型,就直接用Result<String>
Result<String> result = JSON.parseObject(contentAsString, new TypeReference<Result<String>>() {
});
log.info(result.getData());
}

@Test
public void cancelByMember_noParams() throws Exception {
Orders order = new Orders();
ResultActions resultActions = mockMvc.perform(
    put("/order/cancelByMember")
    .contentType(MediaType.APPLICATION_JSON)
    .content(JSON.toJSONString(order))
).andExpect(MockMvcResultMatchers.jsonPath("$.code").value(ResponseEnum.INVALID_PARAMETERS.getCode()))
.andExpect(MockMvcResultMatchers.jsonPath("$.msg").value(ResponseEnum.INVALID_PARAMETERS.getMessage()))
.andExpect(MockMvcResultMatchers.jsonPath("$.success").value(false))
.andExpect(MockMvcResultMatchers.jsonPath("$.data").value("订单id不能为空"));
;
String contentAsString = resultActions.andReturn().getResponse().getContentAsString();
Result<Object> result = JSON.parseObject(contentAsString, new TypeReference<Result<Object>>() {
});
log.info(result.getData().toString());
}


案例2

@GetMapping("details/{oId}")
public Result<Object> getDetails(@PathVariable @NotBlank(message = "订单id不能为空") String oId) {
    OrderVo order = ordersService.getDetails(oId);
    if (order != null) {
        return Result.success(order);
    }
    return Result.error(ResponseEnum.GET_DETAIL_ERROR);
}

@Test
public void getDetails_success() throws Exception {
String oId = "20240912694cf3e4907d4b28b40b5101";
ResultActions resultActions = mockMvc.perform(
    get("/order/details/{oId}", oId)//这样传参
)
.andExpect(MockMvcResultMatchers.jsonPath("$.code").value(ResponseEnum.SUCCESS.getCode()))
.andExpect(MockMvcResultMatchers.jsonPath("$.msg").value(ResponseEnum.SUCCESS.getMessage()))
.andExpect(MockMvcResultMatchers.jsonPath("$.success").value(true))
.andExpect(MockMvcResultMatchers.jsonPath("$.data").isNotEmpty());


String contentAsString = resultActions.andReturn().getResponse().getContentAsString();
Result<OrderVo> result = JSON.parseObject(contentAsString, new TypeReference<Result<OrderVo>>() {
});
log.info(result.getData().toString());
}


案例3

假设ordersController里面的repetition接口尚未实现,然而其他接口的测试需要调用到这个接口,那么可以用MockBean来模拟这个接口的返回

@MockBean
private OrdersController ordersController;

@Test
public void Simulate() throws Exception {
    String oId = "20240912694cf3e4907d4b28b40b5101";
    Result<Object> error = Result.error("模拟这个订单无法复现");
    //但是实际上它是可以复现的

    //当传入这个oId时,返回值为error(模拟出来的,相当于假数据)
    Mockito.when(ordersController.repetition(oId)).thenReturn(error);


    ResultActions resultActions = mockMvc.perform(
                    post("/order/repetition/{oId}", oId)
                            .accept(MediaType.APPLICATION_JSON + ";charset=UTF-8")//以json的格式接收响应
            )
            .andExpect(MockMvcResultMatchers.jsonPath("$.code").value(ResponseEnum.UNKNOWN_ERROR.getCode()))
            .andExpect(MockMvcResultMatchers.jsonPath("$.msg").value(ResponseEnum.UNKNOWN_ERROR.getMessage()))
            .andExpect(MockMvcResultMatchers.jsonPath("$.success").value(false));
}

注意:

这个MockBean注入后导致上面三个测试全部失效

这是因为MockBean的注入可能导致测试的上下文发生改变,他应该与其他测试(不需要模拟接口的)分开,单独测。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值