When using @WithUserDetails in a JUnit 5 Nested Test, userDetailsService is not found.

Error:

java.lang.IllegalStateException: Unable to create SecurityContext using @org.springframework.security.test.context.support.WithUserDetails(setupBefore=TEST_METHOD, userDetailsServiceBeanName=jpaUserDetailsService, value=spring)

Working Test:

        @WithUserDetails(value = "spring", userDetailsServiceBeanName = "jpaUserDetailsService")
        @Test
        void listOrdersAdminAuth() throws Exception {
            mockMvc.perform(get(API_ROOT + stPeteCustomer.getId()))
                    .andExpect(status().isOk());
        }

Failing Test:

    @DisplayName("Create Test")
    @Nested
    class createOrderTests {
        @WithUserDetails(value = "spring", userDetailsServiceBeanName = "jpaUserDetailsService")
        @Test
        void listOrdersAdminAuth() throws Exception {
            mockMvc.perform(get(API_ROOT + stPeteCustomer.getId()))
                    .andExpect(status().isOk());
        }
    }

NOTE: Error is same with or without setting userDetailsServiceBeanName

Comment From: rwinch

This happens because the UserDetailsService is not found in the ApplicationContext of the nested class. Below you can find a complete and simplified test that demonstrates the issue without Spring Security.

package example;

import org.junit.jupiter.api.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.*;
import org.springframework.test.context.junit.jupiter.web.SpringJUnitWebConfig;

@SpringJUnitWebConfig
public class SimpleTest {

    @Test
    void found(@Autowired UserDetailsService userDetailsService) {
    }

    @Nested
    class NestedFailTests {
        @Test
        void nestedFails(@Autowired UserDetailsService userDetailsService) throws Exception {

        }
    }

    @Nested
    @SpringJUnitWebConfig(Config.class)
    class AnnotatedNestedTests {
        @Test
        void annotatedNestedWorks(@Autowired UserDetailsService userDetailsService) throws Exception {

        }
    }

    @Configuration
    static class Config {

        @Bean
        UserDetailsService foo() {
            return new UserDetailsService();
        }
    }

    static class UserDetailsService {}
}

The nested classes don't inherit the ApplicationContext from the parent test class. You can fix this by annotating the nested class to pick up the configuration as shown with AnnotatedNestedTests.

Comment From: sbrannen

This is a known issue and effectively a duplicate of https://github.com/spring-projects/spring-framework/issues/19930 in spring-test.

Comment From: rwinch

Thanks @sbrannen!