使用 MockMvc 时是不是可以添加断言消息?

Posted

技术标签:

【中文标题】使用 MockMvc 时是不是可以添加断言消息?【英文标题】:Is it possible to add an assertion message when using MockMvc?使用 MockMvc 时是否可以添加断言消息? 【发布时间】:2020-10-29 20:14:36 【问题描述】:

大多数时候,我们不是在普通的JUnit 断言中添加 cmets,而是在断言中添加一条消息,以解释为什么这是断言在它所在的位置:

Person p1 = new Person("Bob");
Person p2 = new Person("Bob");
assertEquals(p1, p2, "Persons with the same name should be equal.");

现在,当涉及到 Spring Boot Web 环境中的端点测试时,我最终得到了:

// Bad request because body not posted
mockMvc.perform(post("/postregistration")).andExpect(status().isBadRequest());

// Body posted, it should return OK
mockMvc.perform(post("/postregistration").content(toJson(registrationDto))
        .andExpect(status().isOk()));

有没有办法摆脱 cmets 并为这种断言添加消息?所以,当测试失败时,我会看到消息。

【问题讨论】:

一个想法是调用failIfNoBodyPosted之类的测试方法,这样当测试失败时你就知道原因了。 @marc 嗯,是的,我以前想过,但我不喜欢它。测试一个有 10 个端点的控制器,每个端点有 5-6 个测试用例,我最终会得到 60 个名称相似的方法,并且我将无法知道哪个方法引用了哪个端点测试。就个人而言,当涉及到(简单的)端点测试用例时,我喜欢类似脚本的代码。 【参考方案1】:

我发现assertDoesNotThrow 做出响应从而改善了情况(根据我的要求):

assertDoesNotThrow(() -> 
    mockMvc.perform(post("/postregistration")).andExpect(status().isBadRequest());
, "Bad Request expected since body not posted.");

【讨论】:

我不会将我的答案标记为已接受,以防有人有更好的东西(更少代码的方法)或MockMvc 有一个我不知道的内置东西。 当您链接更多.andExpect() 子句时,这可能不够灵活。【参考方案2】:

您可以提供自定义的 ResultMatcher:

mockMvc.perform(post("/postregistration")
        .content(toJson(registrationDto))
        .andExpect(result -> assertEquals("Body posted, it should return OK", HttpStatus.OK.value() , result.getResponse().getStatus())))

mockMvc.perform(post("/postregistration"))
       .andExpect(result -> assertEquals("Bad request because body not posted", HttpStatus.BAD_REQUEST.value(), result.getResponse().getStatus()));

说明

截至今天,.andExpect() 方法只接受一个 ResultMatcher。当您使用.andExpect(status().isOk()) 时,StatusResultMatchers 类会以这种方式创建一个 ResultMatcher:

public class StatusResultMatchers 
    //...
    public ResultMatcher isOk() 
        return matcher(HttpStatus.OK);
    
    //...
    private ResultMatcher matcher(HttpStatus status) 
        return result -> assertEquals("Status", status.value(), result.getResponse().getStatus());
    


如您所见,消息被硬编码为“状态”,并且没有其他内置方法可以对其进行配置。因此,即使提供自定义 ResultMatcher 有点冗长,但目前可能是使用 mockMvc 的唯一可行方式。

【讨论】:

以上是关于使用 MockMvc 时是不是可以添加断言消息?的主要内容,如果未能解决你的问题,请参考以下文章

Gtest学习系列三:断言

是否可以使用 @AutoConfigureRestDocs 来保证而不是 mockmvc?

assert断言

MockMVC 不是自动装配的,它是空的

用soapui功能测试-使用断言

当普罗米修斯端点正在调用时,MockMvc 收到 404