Spring Security, JUnit: @WithUserDetails для пользователя, созданного в @Before

в тестах JUnit с Spring MockMVC существует два метода проверки подлинности пользователя Spring Security:@WithMockUser создает фиктивного пользователя с учетными данными @WithUserDetails принимает имя пользователя и разрешает его на правильный пользовательский UserDetails реализация с пользовательским UserDetailsService (the UserDetailsServiceImpl).

в моем случае UserDetailsService загружает пользователя из базы данных. Пользователь я хочу, чтобы вставить в @Before метод тестов.

мой UserDetailsServiceImpl не находит пользователя.

в своем @Before, я вставляю пользователя так:

User u = new User();
u.setEMail("test@test.de");
u = userRepository.save(u);

и 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;
}

как я могу использовать учетную запись, созданную в @Before С @WithUserDetails?

2 ответов


к сожалению, вы не можете легко сделать @WithUserDetails с @Before, потому что Spring @withuserdetails аннотация вызовет Spring Security context test listener перед запуском метода установки с @Before.

вот https://stackoverflow.com/a/38282258/1814524 маленький трюк и ответ на ваш вопрос.


@Inject
private EntityManager em;

@Inject
PlatformTransactionManager txManager;

@BeforeTransaction
public void setup() {
    new TransactionTemplate(txManager).execute(status -> {

        User u = new User();
        u.setEMail("test@test.de");
        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 = "test@test.de", userDetailsServiceBeanName = "loadUserByUsername")
public void test() {

}