javaspring-bootunit-testingcsrfmockmvc

How to test with MockMVC and CSRF in Spring Boot 3


I have a SpringBoot MockMVC Test where I want to test a post endpoint like this:

@AutoConfigureTestEntityManager
@SpringBootTest
@AutoConfigureMockMvc
class MyControllerTest {

    @Autowired
    private MockMvc mockMvc;

    @Test
    void postShouldReturnOkForValidInput() throws Exception {
        mockMvc.perform(post(Endpoints.LOG)
            .content(/*Some Valid Input*/)
            .contentType(MediaType.APPLICATION_JSON)
        ).andExpect(status().isOk());
    }
}

However, that test fails due to CSRF protection. Now, I know I can disable it, and then the tests works, but I'd much rather adjust my tests so that they pass along a correct CSRF token.

Now, I have found many sources that say it should work like this:

import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.*;

@AutoConfigureTestEntityManager
@SpringBootTest
@AutoConfigureMockMvc
class MyControllerTest {

    @Autowired
    private MockMvc mockMvc;

    @Test
    void postShouldReturnOkForValidInput() throws Exception {
        mockMvc.perform(post(Endpoints.LOG)
            .with(csrf())
            .content(/*Some Valid Input*/)
            .contentType(MediaType.APPLICATION_JSON)
        ).andExpect(status().isOk());
    }
}

The problem is, it doesn't because the import fails to resolve. Specifically, it says it can't resolve the "test" (after import static org.springframework.security.). I checked, and I do have the dependency implementation 'org.springframework.boot:spring-boot-starter-security'. In fact, import static org.springframework.security, but there's simply no test available among the packages therein.

Now, I know a lot of things changed with Spring 3. Specifically, I am using Version 3.1.4. Is that the reason? Did the csrf() function move somewhere else? If yes, what's the correct way to pass along a CSRF token in Spring Boot 3? And if not, what am I doing wrong here?


Solution

  • The org.springframework.security.test package classes are in spring-security-test library. So you need to add following dependency in your build.gradle file.

    testImplementation 'org.springframework.security:spring-security-test'