Skip to content

@WithUserDetails setupBefore does not work with JUnit 5 #6591

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
sirgrigio opened this issue Mar 5, 2019 · 4 comments
Closed

@WithUserDetails setupBefore does not work with JUnit 5 #6591

sirgrigio opened this issue Mar 5, 2019 · 4 comments
Assignees
Labels
in: test An issue in spring-security-test status: duplicate A duplicate of another issue

Comments

@sirgrigio
Copy link

Summary

When using JUnit 5 it seems that setting the setupBefore parameter of @WithUserDetails to TestExecutionEvent.TEST_EXECUTION does not work as intended. In fact it appears that the security context is created before the execution of a @BeforeEach method.

Actual Behavior

I wrote the following test class to showcase the issue

@ExtendWith(SpringExtension.class)
@ContextConfiguration
class WithUserDetailsTest {

  private static String USERNAME;

  @BeforeEach
  void setUp() {
    USERNAME = "dummy";
  }

  @Test
  @WithUserDetails(
      userDetailsServiceBeanName = "testUserDetailsService",
      setupBefore = TestExecutionEvent.TEST_EXECUTION
  )
  void test() {
    TestUserDetails principal = (TestUserDetails) SecurityContextHolder.getContext()
        .getAuthentication().getPrincipal();
    Assertions.assertNotNull(principal.getUsername());
  }

  @Configuration
  static class TestUserDetailsConfiguration {

    @Bean("testUserDetailsService")
    UserDetailsService testUserDetailsService() {
      return s -> new TestUserDetails(USERNAME);
    }
  }

  static class TestUserDetails implements UserDetails {

    private static final long serialVersionUID = -6779736987183888865L;

    private String username;

    TestUserDetails(String username) {
      this.username = username;
    }

    @Override
    public String getUsername() {
      return username;
    }

    ...
  }
}

What happens here is that the test keeps failing because when the UserDetails is actually loaded the USERNAME variable is still null.

Expected Behavior

I would expect the @BeforeEach method to be executed before the SecurityContext initialization therefore allowing the creation of a UserDetails with a non null username.

Configuration

Version

I am using Spring Boot Dependency 2.1.3.RELEASE (=> Spring Security Test 5.1.4.RELEASE).

Sample

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label May 7, 2019
@jfriedenstab
Copy link

I stumbled upon this issue, too. I would like to create a custom UserDetails object in the @BeforeEach method which can then be used by @WithUserDetails.
Are there any plans to provide a fix for this?

@piotr-karon
Copy link

For anyone with this problem, as this is still not resolved.
Instead of saving user to repository in @Before or @BeforeEach create separate method annotated with @PostConstruct and save user. Assuming you have correctly implemented custom UserDetailsService and @SpringBootTest picks it (or you provide bean name in @WithUserDetails)

private const val USERNAME = "username"
private val user = User(USERNAME)

@SpringBootTest
@WithUserDetails(USERNAME)
class TestClass @Autowired constructor(
  private val userRepo: UserRepository
){

  @PostConstruct
  fun saveUser(){
    userRepo.save(user)
  }

  @Test
  fun someTest(){
     <user is available here>
  }
}

@jzheaux jzheaux self-assigned this Apr 13, 2020
@jzheaux jzheaux added in: test An issue in spring-security-test and removed status: waiting-for-triage An issue we've not yet triaged labels Apr 13, 2020
@jzheaux jzheaux removed their assignment Apr 14, 2020
MGabr added a commit to MGabr/spring-security that referenced this issue Jun 21, 2020
Currently, there is support for setting up a SecurityContext after @before by
using TestExecutionEvent.TEST_EXECUTION. The current implementation, however,
already creates the SecurityContext in @before and just does not set it yet.
This leads to issues like spring-projects#6591. For the case of @WithUserDetails, the
creation of the SecurityContext already looks up a user from the repository.
If the user was inserted in @before, the user is not found despite using
TestExecutionEvent.TEST_EXECUTION. This commit changes the creation of the
SecurityContext to happen after @before if using
TestExecutionEvent.TEST_EXECUTION.

Closes spring-projectsgh-6591
@sambernet
Copy link

Not specific to JUnit 5, same problem also affects vintage JUnit4 tests.
But looking at the brand new PR this was a general issue with the WithUserDetails and both should be fixed with this change. 🥳
Thanks 👍

@rwinch rwinch closed this as completed in 97ee6d6 Jun 24, 2020
@rwinch rwinch added the status: duplicate A duplicate of another issue label Jun 24, 2020
@rwinch rwinch self-assigned this Jun 24, 2020
@rwinch
Copy link
Member

rwinch commented Jun 24, 2020

This is now fixed via gh-6591 Closing as duplicate of the PR

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: test An issue in spring-security-test status: duplicate A duplicate of another issue
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants