使用Rest Assured Mock MVC测试Patch接口时无法构造JsonMerge Patch对象
解决方案
1. Content-Type配置说明
你接口@PatchMapping注解的consumes属性指定了接收的请求体格式为application/merge-patch+json,注意不要搞混contentType和accept的作用:
contentType:指定你发送给服务端的请求体格式,需要匹配接口的consumes配置,这里必须设置为application/merge-patch+jsonaccept:指定你期望服务端返回的响应格式,和接口的返回格式匹配即可,一般填application/json
2. JSON Merge Patch请求体构造
JSON Merge Patch本身就是差量JSON结构,你不需要手动实例化JsonMergePatchImpl对象,Spring MVC内置的消息转换器会自动将符合格式的请求体解析为接口参数对应的JsonMergePatchImpl实例。
你只需要把需要修改的字段按JSON结构传入即可:有值的字段会覆盖原值,传null的字段会被置空,未传入的字段保持原值。
修正后的测试代码示例
import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.http.MediaType; import java.util.HashMap; import java.util.Map; // 构造差量修改内容 Map<String, Object> mergePatchBody = new HashMap<>(); mergePatchBody.put("status", "PAID"); // 要修改的订单状态 mergePatchBody.put("remark", "已支付"); // 要修改的订单备注 // 如果需要置空某个字段直接传null:mergePatchBody.put("cancelReason", null); // 如果Rest Assured未自动序列化Map,可手动转JSON字符串 ObjectMapper objectMapper = new ObjectMapper(); String patchJson = objectMapper.writeValueAsString(mergePatchBody); Mockito.when(facade.patchOrder(any(Long.class), any(JsonMergePatchImpl.class))).thenReturn(orderDTO); OrderDTO actual = given() .contentType("application/merge-patch+json") .body(patchJson) // 也可以直接传mergePatchBody,只要Rest Assured配置了JSON序列化 .accept(MediaType.APPLICATION_JSON_VALUE) .when() .patch(BASE_URL + "/" + 1L) .then() .assertThat() .statusCode(200) .extract() .as(OrderDTO.class);
注意事项
不要和JSON Patch格式搞混:JSON Patch是带op、path属性的数组结构,而JSON Merge Patch就是普通的单层/多层JSON对象,按你的业务需要传差量字段即可。
内容的提问来源于stack exchange,提问作者Apurv Adarsh
相关产品推荐
相关产品推荐

