I want to test a login controller that is used together with spring security.

The controller is implemented like this:

@Controller
@RequestMapping("/login")
public class LoginController
{
  @GetMapping
  public ModelAndView loginPage(@RequestParam(value = "logout", required = false) String logout,
                                @RequestParam(value = "error", required = false) String error)
  {
    ModelAndView modelAndView = new ModelAndView("login");
    if (logout != null)
    {
      modelAndView.addObject("SUCCESS_MESSAGE", "Logout erfolgreich");
    }
    if (error != null)
    {
      modelAndView.addObject("ERROR_MESSAGE", "Login nicht erfolgreich");
    }
    return modelAndView;
  }

This works perfectly with spring-security's behavior for logouts and invalid login attempts, where the logout and error parameters are an empty string and not null.

For the test, I choose the following setup:

@WebMvcTest(controllers = {LoginController.class}, excludeAutoConfiguration = SecurityAutoConfiguration.class)
class LoginControllerTest
{

  @Autowired
  MockMvc mockMvc;

  @SneakyThrows
  @Test
  void testLogoutPage()
  {
    mockMvc.perform(get("/login?logout"))
           .andExpectAll(status().isOk(),
                         MockMvcResultMatchers.view().name("login"),
                         MockMvcResultMatchers.model().attributeExists("SUCCESS_MESSAGE"));
  }
}

This however leads to the query parameter logout being null in the LoginController, which fails the test. I also tried get("/login").queryParam("logout"), but queryParam(...) does not permit empty values. I could add a dummy value, but this would be inconsistent with the redirect behavior of spring-security. I would prefer to pass an empty query parameter through MockMvc, but this seems to be not possible?

Comment From: FBibonne

@bennypi , slightly modifying the controller because I have not the view defined, these two fixes in the test work for me : 1. replace "/login?logout" with "/login?logout=" in the get 2. replace get("/login?logout") with get("/login).queryParam("logout", "")

Does it work for you ?

NB : the get method is from MockMvcRequestBuilders class