Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring MVC test post method with controller redirect

I have a test:

@Test
public void shouldAddCompany() throws Exception {
    mockMvc.perform(post("/companies")
            .param("name", "companyName"))
            .andExpect(model().attribute("company",
                    hasProperty("name", is("companyName"))));

}

and my controller method looks like that:

@PostMapping("/companies")
public String displayCompaniesPost(@ModelAttribute Company company) {
    companyService.save(company);
    return "redirect:/companies";
}

How can i check company attribute in test? There is a problem because of redirect and status 302.

 java.lang.AssertionError: Model attribute 'company'
 Expected: hasProperty("name", is "companyName")
 but: was null

I think it occurs because controller is going to GET method because of redirection. When I remove this redirection everything is ok, but I don't want to remove that redirection.

EDIT (GetMapping):

@GetMapping({"/", "/companies"})
public String displayCompanies(Model model) {
    model.addAttribute("company", new Company());
    List<Company> companies = companyService.findAll();
    model.addAttribute("companies", companies);
    return "companies";
}

I thought the problem is because of addding attribute with the same name in getMapping, but when I removed it, it still doesn't work.

like image 337
Helosze Avatar asked Aug 23 '17 14:08

Helosze


People also ask

How do I redirect a form to another action in spring spring?

Spring MVC Redirect. In this article, we will learn to redirect request from one action to another by using the prefix redirect: inside the controller class. It depends on the application flow and scenario where to redirect the request. Here, we will redirect a form request to another action after saving the record.

Should I use @webmvctest with Spring Boot?

With @WebMvcTest, Spring Boot provides everything we need to build web controller tests, but for the tests to be meaningful, we need to remember to cover all of the responsibilities. Otherwise, we may be in for ugly surprises at runtime. The example code from this article is available on github.

How to test the correct HTTP method in mockmvc?

We simply call the perform () method of MockMvc and provide the URL we want to test: Aside from verifying that the controller responds to a certain URL, this test also verifies the correct HTTP method ( POST in our case) and the correct request content type.

How do I use postmapping in controller?

The controller method is annotated with @PostMapping to define the URL, HTTP method and content type it should listen to. It takes input via parameters annotated with @PathVariable, @RequestBody , and @RequestParam which are automatically filled from the incoming HTTP request.


1 Answers

You need to modify your approach. If you POST to a controller method, and it returns a Redirect you will have no ability to access any model information set by that controller, it just returns an HTTP 302 with a Location Header to the client telling it the new url to go to (in this case GET /companies). If this is a strictly Unit test, that is the extent of what you can test for this method.

I would consider instead treating this as an integration test, and change your test to have two separate steps:

  1. POST /companies and validate that the response is the expected redirect
  2. GET /companies and validate that the list of companies returned contains the new company you posted in step 1
like image 110
Ben M Avatar answered Nov 15 '22 11:11

Ben M