Я пишу простой тест аутентификации с JUnit4 и TestContainers.Оба моих метода @Before
и @After
являются @Transactional
, но когда я запрашиваю данные в UserDetailsServiceImpl
, их нет, и я не могу понять, почему.Там нет ничего асинхронного.Любые идеи.
@Slf4j
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.DEFINED_PORT)
@TestPropertySource(locations = "classpath:application-test.properties")
public abstract class DBEnabledTest {
@Autowired
protected EntityManager em;
@ClassRule
public static PostgreSQLContainer<?> sqlContainer = new PostgreSQLContainer<>("postgres:11")
.withDatabaseName("test_scenarios")
.withUsername("postgres")
.withPassword("postgres");
@BeforeClass
public static void setupEnv() {
System.setProperty("spring.datasource.url", sqlContainer.getJdbcUrl());
System.setProperty("spring.datasource.username", sqlContainer.getUsername());
System.setProperty("spring.datasource.password", sqlContainer.getPassword());
log.info("Running DB test with - " + sqlContainer.getJdbcUrl());
}
@After
@Transactional
public void truncateDb() {
List<String> tables = em.createNativeQuery("SELECT table_name FROM information_schema.tables WHERE table_schema = 'public'").getResultList();
for (String table : tables) {
em.createNativeQuery("TRUNCATE TABLE " + table + " CASCADE").executeUpdate();
}
}
}
@AutoConfigureMockMvc
public class TestUserAuthentication extends DBEnabledTest {
@Autowired
private TestRestTemplate restTemplate;
@Autowired
private UserRepository userRepository;
@Before
@Transactional
public void initDBForEachTestMethod() {
User testUser = new User();
testUser.setEmail("test@user.com");
testUser.setPassword(new BCryptPasswordEncoder().encode("testUser1"));
testUser.setFirstName("Jonh");
testUser.setLastName("Dough");
testUser.setRole(AppRole.USER);
userRepository.saveAndFlush(testUser);
}
@Test
@Transactional
public void test_authenticationSuccess() throws Exception {
ResponseEntity<String> res =
restTemplate.postForEntity(
"/api/user/login",
JsonUtil.objectBuilder()
.put("email", "test@user.com")
.put("password", "testUser1")
.toString(),
String.class
);
assertTrue(res.getStatusCode().is2xxSuccessful());
String body = res.getBody();
JsonNode node = JsonUtil.nodeFromString(body);
assertNotNull(node.get("id"));
assertNotNull(node.get("token"));
assertNotNull(node.get("refreshToken"));
assertNotNull(node.get("expiresAt"));
DecodedJWT decodedJWT = JWTUtil.verifyToken(node.get("token").asText(), jwtConfig.getSecret());
assertEquals("test@user.com", decodedJWT.getSubject());
assertEquals(AppRole.USER, AppRole.valueOf(decodedJWT.getClaim(JWTUtil.ROLE_CLAIM).asString()));
}
}
@Component
public class UserDetailsServiceImpl implements UserDetailsService {
@Autowired
private UserRepository userRepository;
@Override
public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
com.concentric.scenarios.domain.user.User applicationUser = userRepository.findByEmail(email);
// data from @Before not available here !!!
if (applicationUser == null || applicationUser.isDeleted()) {
throw new UsernameNotFoundException(email);
}
if(applicationUser.getPassword() == null) {
throw new IllegalAccessError();
}
return new org.springframework.security.core.userdetails.User(email, applicationUser.getPassword(), new ArrayList<>());
}
}