Spring Flash Scope Redirection and Unit Testing

When redirecting from one endpoint to another, you can use the flash scope to inherit the parameters to the redirect destination.

controller

When accessing / from with GET with the following controller, redirect to / to. In the process of the redirect source, the bookName and buyerList are pushed into the flash scope and taken over to the redirect destination.

package com.example.demo.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import java.util.Arrays;
import java.util.List;

@Controller
public class DemoController {

    @GetMapping(path = "/from")
    public String from(RedirectAttributes redirectAttributes) {

        redirectAttributes.addFlashAttribute("bookName", "Doraemon");

        List<String> buyerList = Arrays.asList("Nobi", "Gouda");
        redirectAttributes.addFlashAttribute("buyerList", buyerList);

        return "redirect:/to";
    }

    @GetMapping(path = "/to")
    public String to(Model model) {
        System.out.println(model);
        return "demo";
    }
}

When you access / from, you will be redirected to / to and the inherited parameters will be displayed on the console.

{bookName=Doraemon, buyerList=[Nobi,Gouda]}

point

--Set RedirectAttributes as an argument in the redirect source method, and specify the attribute name and contents to be inherited in .addFlashAttribute. The attribute name can be omitted, but in that case, the attribute name is automatically set according to the class name. --At the redirect destination, attribute is included in the Model set in the argument. If you want to refer to the contents, specify the attribute name with .getAttribute.

Unit test

Make sure that when you access / from, you will inherit the parameters and be redirected to / to.

package com.example.demo.controller;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;

import java.util.Arrays;

import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.flash;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.redirectedUrl;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
public class DemoControllerTest {

    @Autowired
    MockMvc mockMvc;

    @Test
    public void redirectWithAttributes() throws Exception {
        mockMvc.perform(get("/from"))
                .andExpect(status().isFound())
                .andExpect(redirectedUrl("/to"))
                .andExpect(flash().attribute("bookName", "Doraemon"))
                .andExpect(flash().attribute("buyerList", Arrays.asList("Nobi", "Gouda")));
    }
}

point

--Check with ʻandExpect ()that it works as expected. --Check that the HTTP status is302 with status (). isFound () . --Assert the redirect destination path with redirectedUrl (). --Assertions for parameters to be inherited by flash (). Attribute ()`.

Extraction by FlashMap

You can retrieve the takeover parameters with FlashMap as follows. Use this if you want to confirm that there are no extra parameters or if you cannot make an assertion with a simple character string expression.


    @Test
    public void redirectWithAttributes() throws Exception {

        MvcResult mvcResult = mockMvc.perform(get("/from"))
                .andExpect(status().isFound())
                .andExpect(redirectedUrl("/to"))
                .andReturn();

        FlashMap flashMap = mvcResult.getFlashMap();

        assertThat(flashMap.size()).isEqualTo(2);
        assertThat(flashMap.get("bookName")).isEqualTo("Doraemon");
        assertThat(flashMap.get("buyerList")).isEqualTo(Arrays.asList("Nobi", "Gouda"));

Recommended Posts

Spring Flash Scope Redirection and Unit Testing
About designing Spring Boot and unit test environment
Testing JPA entities and repositories using Spring Boot @DataJpaTest