单元测试 - 使用 MockMvc 使用 @RequestHeader 和 HashMap 测试控制器

Posted

技术标签:

【中文标题】单元测试 - 使用 MockMvc 使用 @RequestHeader 和 HashMap 测试控制器【英文标题】:Unit Test - Using MockMvc to test the controller with @RequestHeader with HashMap 【发布时间】:2021-03-14 19:24:02 【问题描述】:

我有一个具有以下结构的控制器:

@RequestMapping(value="/validate", method=RequestMethod.POST)
    public ResponseEntity<Jwt> IsValid(@RequestBody UserRequest userRequest, @RequestHeader Map<String, String> header) throws Exception 
    if(header.contains("key") && header.contains("secret") 
        process(header.get("key"), header.get("secret"));
        ...
        ...
    
 

我正在使用 MockMvc 为这个控制器编写一个单元测试:

@RunWith(SpringRunner.class)
@AutoConfigureMockMvc
@SpringBootTest
public class AuthenticatorServiceTest 

    @Autowired
    private MockMvc mockMvc;

    @Test
    public void CorrectKeyValidation throws Exception 
        String key = "correct-key";
        String secret = "correct-secret";
        Map<String, String> map = new HashMap<>();
        map.put("key", key);
        map.put("secret", secret);

        MvcResult result = mockMvc.perform(MockMvcRequestBuilders.post("/validate")
                .header() // <- doesn't accept Map here.
                .contentType(MediaType.APPLICATION_JSON))
                .andExpect(status().isOk()).andReturn();
        ...
        ... 
      
 

由于MockMvcRequestBuildersheader 方法只接受字符串,我不确定如何使用MockMvc 来测试我的控制器,其中Map&lt;String, String&gt; 作为@RequestHeader。任何帮助将不胜感激!

【问题讨论】:

@RequestHeader Map&lt;String, String&gt; header 表示它将注入该映射中的所有标题。 感谢您的回复。你能详细说明一下吗?我尝试使用 mockMvc.perform(MockMvcRequestBuilders.post("/validate") .header("key", key) .header("secret", secret) .contentType(MediaType.APPLICATION_JSON)) .andExpect(status() 发送。 isOk()).andReturn();但无法真正让它工作,因为它正在抛出org.springframework.http.converter.HttpMessageNotReadableException。也许我在这里遗漏了一些东西.. 顺便说一句:不要那样做。使用@RequestHeader("key") 【参考方案1】:

还有一个类似下面的方法(.headers(*)),你可以用,刚刚验证过。

Map<String, String> map = new HashMap<>();
        map.put("key", key);
        map.put("secret", secret);
HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.setAll(map);
        MvcResult result = mvc.perform(MockMvcRequestBuilders
                .post("/scheduler/enable")
                .headers(httpHeaders)
                .contentType(MediaType.APPLICATION_JSON_UTF8)
                .content(this.getRequstAsJSON()))
                .andDo(print())
                .andReturn();

希望这是有用的。

【讨论】:

感谢您的回复!我试过了,但我仍然收到以下错误:Handler: Type = com.louprogramming.controller.AuthController Method = public org.springframework.http.ResponseEntity&lt;com.louprogramming.domain.Jwt&gt; com.louprogramming.controller.AuthController.IsValid(com.louprogramming.domain.UserRequest,java.util.Map&lt;java.lang.String, java.lang.String&gt;) throws java.lang.Exception. Resolved Exception: Type = org.springframework.http.converter.HttpMessageNotReadableException.您对为什么会发生这种情况有任何见解吗? 您的 API 是否处于工作状态,意味着您可以使用 Postman 之类的东西,使用您通过测试用例的所有标头来访问您的 API 吗? 谢谢!刚刚通过添加 .content 使其工作。 我看到你的代码有一个问题,我不知道你为什么这样做,但是,@RequestHeader 意味着一次 1 个键/值,更多,你需要重复它。我相信这可能是一个问题。 baeldung.com/spring-rest-http-headers @AjeetMaurya @RequestHeader 也可以使用地图,这甚至是一个记录和支持的案例。见docs.spring.io/spring-framework/docs/current/reference/html/…。请不要传播不真实的信息。

以上是关于单元测试 - 使用 MockMvc 使用 @RequestHeader 和 HashMap 测试控制器的主要内容,如果未能解决你的问题,请参考以下文章

Spring 的 MockMvc 是用于单元测试还是集成测试?

如何正确使用 MockMvc 在 Junit 中测试 post 方法?

MockMvc control层单元测试 参数传递问题

无标题

无标题

无标题