Junit MockMvc 使用 URL 中的路径变量执行 POST,返回 404 未找到

Posted

技术标签:

【中文标题】Junit MockMvc 使用 URL 中的路径变量执行 POST,返回 404 未找到【英文标题】:Junit MockMvc perform POST with path variable in URL return 404 not found 【发布时间】:2020-03-12 00:53:19 【问题描述】:

我有一个 SpringBoot 应用程序,在控制器中使用此方法在数据库中创建用户。控制器在 Postman 中运行良好。

@RestController
@RequestMapping("/v1")
public class UserController 

  @PostMapping(value = "/user/id")
  public void createUser(@PathVariable Integer id, @Valid @RequestBody User request,
        BindingResult bindingResult) throws Exception 

    if (bindingResult.hasErrors())         
        throw new RequestValidationException(VALIDATION_ERRORS, bindingResult.getFieldErrors());
                   
    userService.createUser(id, request), HttpStatus.CREATED);

现在我有一个 junit 测试用例来测试这个方法,我得到一个 404

@RunWith(SpringRunner.class)
@SpringBootTest(classes = MyApp.class)
public class UserTest 

  private MockMvc mockMvc;
  final String CREATE_USER_URL = "/v1/user/" + "10";

  private final MediaType contentType = new MediaType(MediaType.APPLICATION_JSON.getType(),
        MediaType.APPLICATION_JSON.getSubtype(), Charset.forName("utf8"));

@Test
public void testCreateUser() throws Exception  

  mockMvc.perform(post(CREATE_USER_URL)  
   // doesn't work either if I put "/v1/user/10" or post("/v1/user/id", 10) here
            .content(TestUtils.toJson(request, false))
            .contentType(contentType))
            .andDo(print())
            .andExpect(status().isCreated())
            .andReturn();  
 

但在日志中,我能够看到正确的 url:

MockHttpServletRequest:

  HTTP Method = POST
  Request URI = /v1/user/10
  Parameters = 

有人可以告诉我为什么我会收到 404 NOT Found 吗?谢谢。

【问题讨论】:

你能展示完整的测试类吗? @Deadpool 已更新。谢谢 你能发布整个控制器的代码吗?我觉得您缺少将控制器级别的 @RequestMapping 的一部分添加到您的 URL @HirenShah 已更新。谢谢。 【参考方案1】:

从docs 你需要@AutoConfigureMockMvc 上课和@Autowire MockMvc

另一个有用的方法是根本不启动服务器,而只测试下面的层,Spring 处理传入的 HTTP 请求并将其交给您的控制器。这样,几乎使用了整个堆栈,并且您的代码将被调用,就好像它正在处理一个真正的 HTTP 请求一样,但没有启动服务器的成本。为此,我们将使用 Spring 的 MockMvc,我们可以通过在测试用例上使用 @AutoConfigureMockMvc 注释来请求为我们注入它:

代码:

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

   @Autowire
   private MockMvc mockMvc;
   final String CREATE_USER_URL = "/v1/user/" + "10";

   private final MediaType contentType = new MediaType(MediaType.APPLICATION_JSON.getType(),
    MediaType.APPLICATION_JSON.getSubtype(), Charset.forName("utf8"));

  @Test
  public void testCreateUser() throws Exception  

    mockMvc.perform(post(CREATE_USER_URL)  
 // doesn't work either if I put "/v1/user/10" or post("/v1/user/id", 10) here
        .content(TestUtils.toJson(request, false))
        .contentType(contentType))
        .andDo(print())
        .andExpect(status().isCreated())
        .andReturn();  
   

【讨论】:

谢谢。但是在课堂上添加 AutoConfigureMockMvc 和 Autowired MockMvc 后,我仍然得到 404 对不起。它现在正在工作。我复制了错误的注释。非常感谢您的帮助!【参考方案2】:
If want to Test your real springboot url Test (End to end Test)    
u can use  rest-assured or resttemplte 

@RunWith(SpringJUnit4ClassRunner.class)  
@ContextConfiguration(classes = Application.class) 
@TestPropertySource(value="classpath:application.properties")
@SpringBootTest(webEnvironment = WebEnvironment.DEFINED_PORT)
public class SpringRestControllerTest 
    @Value("$server.port") 
    int port;
       @Test
       public void getDataTest() 
              get("/api/tdd/responseData").then().assertThat().body("data", equalTo("responseData"));
       
       @Before
       public void setBaseUri () 
               RestAssured.port = port;
               RestAssured.baseURI = "http://localhost"; // replace as appropriate
       

https://dzone.com/articles/test-driven-development-with-spring-boot-rest-api

【讨论】:

以上是关于Junit MockMvc 使用 URL 中的路径变量执行 POST,返回 404 未找到的主要内容,如果未能解决你的问题,请参考以下文章

为啥我收到 MockMvc 和 JUnit 的错误 403?

使用 spring-data-jpa 和 MockMvc 进行 spring boot junit 测试

MockMVC的使用

我需要创建方法get()和status()来创建一个带有mockmvc的测试控制器?

如何使用 MockMvc 测试弹簧控制器方法?

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