통합 테스트 클래스가 UserController
입니다. 다음 클래스의 내용은 다음과 같습니다봄 부팅 테스트의 트랜잭션이 롤백되지 않습니다.
// imports...
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@RunWith(SpringRunner.class)
@Transactional
@Rollback
public class UserControllerTests {
private static final String ENDPOINT = "/v1/users";
@Autowired
private TestRestTemplate restTemplate;
@Autowired
private ApplicationProperties applicationProperties;
@Test
public void test_user_create() {
String token = login("test", "test");
HttpEntity<UserRequest> request = createRequest(token, "admin", "admin");
ResponseEntity<User> response = restTemplate.exchange(ENDPOINT, HttpMethod.POST, request, User.class);
assertEquals(HttpStatus.CREATED, response.getStatusCode());
}
private HttpEntity createRequest(String token) {
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
headers.set("Authorization", String.format("Bearer %s", token));
return new HttpEntity(headers);
}
private HttpEntity<UserRequest> createRequest(String token, String username, String password) {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
headers.set("Authorization", String.format("Bearer %s", token));
return new HttpEntity<>(new UserRequest(username, password), headers);
}
private String login(String username, String password) {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
headers.set("Authorization", String.format("Basic %s", Base64.getEncoder().encodeToString(String.format("%s:%s", applicationProperties.getAuth().getClientId(), applicationProperties.getAuth().getClientSecret()).getBytes())));
MultiValueMap<String, String> body = new LinkedMultiValueMap<>();
body.add("grant_type", "password");
body.add("username", username);
body.add("password", password);
HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(body, headers);
ResponseEntity<OAuth2AccessToken> response = restTemplate.exchange("/oauth/token", HttpMethod.POST, request, OAuth2AccessToken.class);
return response.getBody().getValue();
}
}
내가 두 번이 테스트 클래스, 이미 이름 admin
(고유 제한 조건)와 데이터베이스의 사용자가 있기 때문에 실패하는 두 번째 시간을 실행합니다.
postgres
데이터베이스에 대해 테스트 중이며, 프로덕션 환경과 같습니다. 응용 프로그램은 데이터베이스 조작을 위해 Spring의 jdbcTemplate
을 사용합니다.
2017-10-13 14:11:31.407 INFO [iam-service,,,] 63566 --- [ main] o.s.t.c.transaction.TransactionContext : Began transaction (1) for test context
...
2017-10-13 14:11:32.050 INFO [iam-service,,,] 63566 --- [ main] o.s.t.c.transaction.TransactionContext : Rolled back transaction for test context
내 응용 프로그램의 흐름이 <request> --> <controller> --> <service with jdbcTemplate>
과 서비스가 @Transactional
와 주석 있습니다
내 기록은 다음과 같은 로그를 생산했다.
저는 정말 이걸 고집합니다. 당신은에서 직접 적용 할 때 지원되지 않습니다
@Bean
public PlatformTransactionManager transactionManager(DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
서비스 레이어의'@ Transactional' 메소드에'REQUIRES_NEW'가 있습니까? – Patrick
@ 패트릭이 작동하지 않습니다 – mmjmanders
그래, 그게 왜 내가 물어 보는거야. 이것은 문제가 될 수 있습니다. – Patrick