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.
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.
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.
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.
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.
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:
/companies
and validate that the response is the expected redirect/companies
and validate that the list of companies returned contains the new company you posted in step 1If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With