Search code examples
javaformsspring-bootjunit

Spring Boot unittest with WebRequest with form submission included


I am writing unittests and I've stumbled across something I can't find a solution for that fits my needs or code I already have.

The User first comes at a page where they have to choose (from a dropdown list) what brand they want to make a configuration for. After they click 'submit', it takes them to a page where all the appropriate settings are listed per category.

Now, the choosing of the brand is a form and it's submitted to this method:

// Display a form to make a new Configuration
    @PostMapping("/addConfig")
    public String showConfigurationForm(WebRequest request, Model model) {
        // Get the ID of the selected brand
        Map<String, String[]> inputMap = request.getParameterMap();
        for (Entry<String, String[]> input : inputMap.entrySet()) {
            if (input.getValue().length > 0
                    && input.getKey().startsWith("brand")) {
                brandId = Integer.parseInt(input.getValue()[0]);
            }
        }
        // Load the view
        model.addAttribute("categoryResult",
                databaseService.getCategories(brandId));
        model.addAttribute("configItemsMap",
                databaseService.getAddConfigItems(brandId));
        return "addConfig";
    }

I want to unittest this method to see if the model has the attributes we expect it to.
This is the unit test I have now:

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
@ActiveProfiles("test")
public class AddConfigurationTest {
    @Autowired
    AddConfigurationController addConfigurationController;

    @MockBean
    DatabaseService databaseServiceTest;
    @Mock
    WebRequest webRequest;

    @Before
    public void setup() {       
        // Make Categories
        List<ItemCategory> defaultCategories = new ArrayList<>();
        defaultCategories.add(new ItemCategory(1, 1, "GPS settings"));

        // Mock it
        Mockito.when(this.databaseServiceTest.getCategories(1)).thenReturn(
            defaultCategories);
    }

    @Test
    public void configurationFormShouldContainCategories() {
        // TODO: Still needs param for webrequest

        // Make a model
        Model model = new ExtendedModelMap();
        addConfigurationController.showConfigurationForm(webRequest, model);
        // Get the list from the model
        @SuppressWarnings("unchecked")
        List<ItemCategory> categoryList = (List<ItemCategory>) model.asMap()
            .get("categoryResult");
        System.out.println(categoryList);
    }
}

The System.out.println now outputs: []

I am sure it has to do with the WebRequest, because as I have it now this WebRequest does not have the input from a form the showConfigurationForm method needs.

My question is: how can I add the right data to WebRequest so the test will return a List? Or is there another way around that I have not figured out?


Solution

  • Just configure your Mock WebRequest object before executing the test:

        @Before
        public void setup()
        {
            Map<String, String[]> mockParameterMap = new HashMap<>();
            mockParameterMap.put("brand00", new String[]{"value01"});
            // add all the parameters you want ...
            Mockito.when(webRequest.getParameterMap())
                    .thenReturn(mockParameterMap);
        }
    

    That should be enough for the example you described.