Search code examples
spring-bootspring-securitymockmvc

Custom Spring Security Filter Test with MockMvc always returns 404


I am trying to test a custom filter using MockMvc and it always returns status 404 instead of the actual status returned from the filter class. The filter class looks as follows:

    public class CustomFilter extends GenericFilterBean {

        @Override
        public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain)
            throws IOException, ServletException {

            HttpServletRequest request = (HttpServletRequest) servletRequest;
            // some logic 
            chain.doFilter(servletRequest, servletResponse);
        }
    }

This is registered in with the SpringBootApplication using FilterRegistrationBean

    @SpringBootApplication
    public class MyApplication {

        public static void main(String[] args) {
           try {
              ConfigurableApplicationContext ctx = SpringApplication.run(MyApplication.class, args);
           } catch (Throwable e) {
        }

        @Bean
        public FilterRegistrationBean<CustomFilter> customFilter() {
           FilterRegistrationBean<CustomFilter> filterRegistration = new FilterRegistrationBean<>();
           filterRegistration.setFilter(new CustomFilter());
           filterRegistration.addUrlPatterns("/test/*");
           return filterRegistration;
        }
    }

The test for this is written as follows:

    @RunWith(SpringRunner.class)
    @SpringBootTest(CustomFilter.class)
    @EnableAutoConfiguration 
    @WebAppConfiguration
    public class CustomFilterTest {

        @Autowired
        private CustomFilter filter;

        @Autowired
        private WebApplicationContext context;

        private MockMvc mvc;

        @Before
        public void setup() {
            this.mvc = MockMvcBuilders.webAppContextSetup(context)
                 .addFilters(filter)
                 .build();
        }

        @Test
        public void testCustomFilter() throws Throwable {

           MockHttpServletRequestBuilder request = MockMvcRequestBuilders
                .request(HttpMethod.POST, "/resource/abc")
                .header("SomeHeader", "xxx")
                .content("{}");

           MockHttpServletResponse response = mvc.perform(request).andReturn().getResponse();

           assertEquals(response.getStatus(), HttpServletResponse.SC_CONTINUE);
        }
    }

The assertion always returns the status value of 404.

Am I missing something here?


Solution

  • Add urlPatterns to the addFilter(filter, "/resource/abc") and add a test controller for the above code snippet as follows:

    @RestController
    public class TestController {
    
        @PostMapping("/resource/abc")
        public void testSecureEndpoint() {
    
        }
    }