1

I have a SpringBoot application with this method in the controller to create an user in the database. The controller is working fine in 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);
}

Now I have a junit test case to test this method and I am getting a 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();  
 }

But in the log, I was able to see the correct url:

MockHttpServletRequest:

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

Can someone please let me know why I am getting a 404 NOT Found? Thanks.

4
  • 1
    can you show the complete test class ? Commented Nov 15, 2019 at 20:38
  • @Deadpool Updated. Thanks Commented Nov 15, 2019 at 20:44
  • can you post the code for entire controller? I feel you are missing to add part of @RequestMapping at controller level into your URL Commented Nov 15, 2019 at 20:57
  • @HirenShah updated. Thanks. Commented Nov 15, 2019 at 21:02

2 Answers 2

2

From docs you need @AutoConfigureMockMvc on class and @Autowire MockMvc

Another useful approach is to not start the server at all, but test only the layer below that, where Spring handles the incoming HTTP request and hands it off to your controller. That way, almost the full stack is used, and your code will be called exactly the same way as if it was processing a real HTTP request, but without the cost of starting the server. To do that we will use Spring’s MockMvc, and we can ask for that to be injected for us by using the @AutoConfigureMockMvc annotation on the test case:

Code :

@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();  
   }
}
Sign up to request clarification or add additional context in comments.

2 Comments

Thank you. But I am still getting 404 after added AutoConfigureMockMvc on class and Autowired MockMvc
Sorry. It is working now. I was copying the wrong annotation. Thank you very much for helping!
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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.