是否有任何适当的匹配器来解析和比较来自 MockMvc 的 Json 响应中的 LocalDateTime 字段

Posted

技术标签:

【中文标题】是否有任何适当的匹配器来解析和比较来自 MockMvc 的 Json 响应中的 LocalDateTime 字段【英文标题】:Is there any proper matcher to parse and compare LocalDateTime field in Json response from MockMvc 【发布时间】:2019-08-29 20:33:20 【问题描述】:

我正在测试我的 SpringBoot 控制器的 get 方法,该控制器提供对象,在特定时间范围内以基础编写。

我意识到我可以在 mockMvc 执行后获取 json,并使用对象映射器解析它,使用一些流和一个断言,但我想知道是否有内置的方法可以使用 andExpect() 序列。

我试过 Hamcrest 日期匹配器,但它无法解析 LocalDateTime 格式 java.lang.AssertionError: JSON path "data.SENT[0].sentAt" Expected: the date is within 10 days of "08 апр 2019 19:03:48 614ms +0300" but: was "2019-04-02T11:36:16.51"

this.mockMvc.perform(get(BASE_URL)
                .accept(MediaType.APPLICATION_JSON_VALUE)
                .contentType(MediaType.APPLICATION_JSON)
                .content(jsonMockObjectMapper.writeValueAsString(smsStatisticFullRequest)))
                .andExpect(status().isOk())
                .andExpect(jsonPath("data.SENT[*].sentAt", Matchers.hasItems("2019-04-02T11:36:16.51")))
//              .andExpect(jsonPath("data.SENT[0].sentAt", DateMatchers.within(10, TimeUnit.DAYS, Timestamp.valueOf(LocalDateTime.now()))))
//              .andExpect(jsonPath("data.SENT[0].sentAt", DateMatchers.before(Timestamp.valueOf(LocalDateTime.now()))))
                .andDo(CustomResultHandler.handleResult(name.getMethodName(), MockMvcRestDocumentation::document));

我希望能够检查返回数据中的所有对象是否在断​​言时间范围内。

Content-Type: application/json;charset=UTF-8
Cache-Control: no-cache, no-store, max-age=0, must-revalidate


  "apiVersion" : "1.0.1",
  "error" : false,
  "data" : 
    "SENT" : [ 
      "id" : 3,
      "phone" : "9111233456",
      "userId" : 683581,
      "sentAt" : "2019-04-02T11:36:16.51",
      "operation" : "RECOVERY_PASSWORD",
      "smsCode" : "2112"
     ],

我可以检查是否有一些具体的对象。但是我不能确定我的退货数据中没有时间段的记录。

【问题讨论】:

【参考方案1】:

我已经制作了自己的匹配器:


import net.minidev.json.JSONArray;
import org.hamcrest.BaseMatcher;
import org.hamcrest.Description;

import java.time.LocalDateTime;

class CustomMatcher extends BaseMatcher<LocalDateTime> 

    private LocalDateTime from;
    private LocalDateTime to;
    private int misMatchAtIndex;

    CustomMatcher(LocalDateTime from, LocalDateTime to) 
        this.from = from;
        this.to = to;
    

    @Override
    public boolean matches(Object item) 
        JSONArray rawData = (JSONArray) item;
        for (Object raw : rawData) 
            LocalDateTime parsed = LocalDateTime.parse(raw.toString());
            if (!parsed.isBefore(to) || !parsed.isAfter(from)) 
                misMatchAtIndex = rawData.indexOf(raw);
                return false;
            
        
        return true;
    

    @Override
    public void describeTo(Description description) 
        description.appendText(String.format("All DateTime fields from %s to %s, mismatch at index %d",
                from, to, misMatchAtIndex));
    

使用:

 .andExpect(jsonPath("data." + SENT + "[*].sentAt", new CustomMatcher(fromDate, toDate)))

【讨论】:

以上是关于是否有任何适当的匹配器来解析和比较来自 MockMvc 的 Json 响应中的 LocalDateTime 字段的主要内容,如果未能解决你的问题,请参考以下文章

为啥 Spring 的 `AuthenticationWebFilter` 有自己的匹配器来检查请求是不是需要身份验证?

vueJs 路由组件增加解析:你可能需要合适的加载器来处理这种文件类型

我如何解析来自 openlibrary api 的 Json 数据? (适当地)

是否可以使用任何 html 加密器来加密 paypal html 代码?

使用 NextJS 和 Next-CSS 做出反应:您可能需要适当的加载器来处理这种文件类型

JQuery 检查类是不是匹配