Spring Security, JUnit: @WithUserDetails for user created in @Before
Solution 1
Unfortunately, you can't do easily @WithUserDetails
with @Before
, because Spring @WithUserDetails
annotation will invoke Spring security context test listener before running setUp
method with @Before
.
Here is https://stackoverflow.com/a/38282258/1814524 a little trick and answer to your question.
Solution 2
You can use @PostConstruct
instead of @Before
. That did the trick for me. Can anybody confirm that?
Solution 3
@Inject
private EntityManager em;
@Inject
PlatformTransactionManager txManager;
@BeforeTransaction
public void setup() {
new TransactionTemplate(txManager).execute(status -> {
User u = new User();
u.setEMail("[email protected]");
em.save(u);
return null;
});
}
@AfterTransaction
public void cleanup() {
new TransactionTemplate(txManager).execute(status -> {
// Check if the entity is managed by EntityManager.
// If not, make it managed with merge() and remove it.
em.remove(em.contains(u) ? user1 : em.merge(u));
return null;
});
}
@Test
@Transactional
@WithUserDetails(value = "[email protected]", userDetailsServiceBeanName = "loadUserByUsername")
public void test() {
}
Solution 4
Use setupBefore = TEST_EXECUTION
This will effectively cause @WithUserDetails
to execute after @Before
and @BeforeEach
@BeforeEach
public void createUser() {
...
}
@Test
@WithUserDetails(value = "username", setupBefore = TestExecutionEvent.TEST_EXECUTION)
public void expectToWork() {
...
}
fNek
Updated on June 06, 2022Comments
-
fNek almost 2 years
In JUnit tests with Spring MockMVC, there are two methods for authenticating as a Spring Security user:
@WithMockUser
creates a dummy user with the provided credentials,@WithUserDetails
takes a user's name and resolves it to the correct customUserDetails
implementation with a customUserDetailsService
(theUserDetailsServiceImpl
).In my case, the
UserDetailsService
loads an user from the database. The user I want to use was inserted in the@Before
method of the test suite.However, my
UserDetailsServiceImpl
does not find the user.In my
@Before
, I insert the user like this:User u = new User(); u.setEMail("[email protected]"); u = userRepository.save(u);
And in the
UserDetailsServiceImpl
:public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { User user = this.userRepository.findOneByEMail(username); if (user == null) throw new UsernameNotFoundException(String.format("No user found with username '%s'.", username)); return user; }
How can I use an account created in
@Before
with@WithUserDetails
?