Search code examples
javaspringspring-bootspring-test

Setting SecurityContextHolder.setContext(...) to a mock carries across to different test classes even with @DirtiesContext


In one of my test classes, I use:

//Make a security context
SecurityContext securityContext = mock( SecurityContext.class );
SecurityContextHolder.setContext( securityContext );

And then I set some things on it.

In another test class, I get a failure due to that mock still being in there. I added @DirtiesContext on all of the test classes but it still happens. When I check the class of the security context in the 2nd class, it says it's a mock.

How do I properly reset everything between classes?

The first class is run as:

@RunWith( SpringJUnit4ClassRunner.class )
@SpringBootTest(
    webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT
)
@DirtiesContext

And the second is just:

@RunWith( SpringJUnit4ClassRunner.class )
@DirtiesContext

Solution

  • The word "context" is confusing you.

    Those are two very different "contexts".

    @DirtiesContext is related to the test ApplicationContext; whereas, the SecurityContext is part of Spring Security and had nothing to do with the ApplicationContext.

    Thus, if you set a SecurityContext in Spring Security's SecurityContextHolder, it is your job to remove it once your test completes.

    The latter requires manual work on your part. If you want Spring Security's testing support to take care of everything, you'll likely be happier with @WithMockUser and related testing support in spring-security-test.