[SPRING] 봄 부팅 테스트 @ 거래가 저장되지 않음
SPRING봄 부팅 테스트 @ 거래가 저장되지 않음
나는 e2e 유즈 케이스를 테스트하기 위해 Spring Boot Test를 사용하여 간단한 통합 테스트를 시도하고있다. 저장소를 데이터를 저장할 수 없기 때문에 내 테스트가 작동하지 않는다. 스프링 컨텍스트에 문제가 있다고 생각한다.
이것은 나의 실체입니다.
@Entity
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class Person {
@Id
private int id;
private String name;
}
이는 Person 저장소입니다.
@Repository
public interface PersonRepository extends JpaRepository<Person, Integer> {
}
사람 서비스 :
@Service
public class PersonService {
@Autowired
private PersonRepository repository;
public Person createPerson(int id,String name) {
return repository.save(new Person(id, name));
}
public List<Person> getPersons() {
return repository.findAll();
}
}
개인용 제어기 :
@RequestMapping
@RestController
public class PersonController {
@Autowired
private PersonService personService;
@RequestMapping("/persons")
public List<Person> getPersons() {
return personService.getPersons();
}
}
주요 응용 프로그램 클래스 :
@SpringBootApplication
public class BootIntegrationTestApplication {
public static void main(String[] args) {
SpringApplication.run(BootIntegrationTestApplication.class, args);
}
}
application.properties 파일은 다음과 같습니다.
spring.datasource.url= jdbc:mysql://localhost:3306/test
spring.datasource.username=root
spring.datasource.password=password
spring.jpa.hibernate.ddl-auto=create
spring.jpa.show-sql=true
그리고 테스트 :
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class BootIntegrationTestApplicationTests {
@Autowired
private PersonService personService;
@Autowired
private TestRestTemplate restTemplate;
@Test
@Transactional
public void contextLoads() {
Person person = personService.createPerson(1, "person1");
Assert.assertNotNull(person);
ResponseEntity<Person[]> persons = restTemplate.getForEntity("/persons", Person[].class);
}
}
서비스가 Person 엔티티를 저장하지 않기 때문에 테스트가 작동하지 않습니다. 미리 감사드립니다.
해결법
-
==============================
1.M. Deinum에게 감사드립니다. 따라서 테스트의 논리를 두 가지 테스트로 구분하는 것이 가장 좋습니다. 첫 번째 테스트는 서비스 만 테스트하므로 (이 경우 트랜잭션 일 수 있음) 두 번째 테스트는 컨트롤러입니다.
M. Deinum에게 감사드립니다. 따라서 테스트의 논리를 두 가지 테스트로 구분하는 것이 가장 좋습니다. 첫 번째 테스트는 서비스 만 테스트하므로 (이 경우 트랜잭션 일 수 있음) 두 번째 테스트는 컨트롤러입니다.
시험 1 :
@Test @Transactional public void testServiceSaveAndRead() { personService.createPerson(1, "person1"); Assert.assertTrue(personService.getPersons().size() == 1); }
시험 2 :
@MockBean private PersonService personService; @Before public void setUp() { //mock the service given(personService.getPersons()) .willReturn(Collections.singletonList(new Person(1, "p1"))); } @Test public void testController() { ResponseEntity<Person[]> persons = restTemplate.getForEntity("/persons", Person[].class); Assert.assertTrue(persons.getBody()!=null && persons.getBody().length == 1); }
언젠가 누군가에게 도움이되기를 바랍니다.
-
==============================
2.DB 트랜잭션을 만드는 각 @Test 함수에 대해 변경 사항을 영구적으로 유지하려면 @Rollback (false)을 사용할 수 있습니다.
DB 트랜잭션을 만드는 각 @Test 함수에 대해 변경 사항을 영구적으로 유지하려면 @Rollback (false)을 사용할 수 있습니다.
@Rollback(false) @Test public void createPerson() throws Exception { int databaseSizeBeforeCreate = personRepository.findAll().size(); // Create the Person restPersonMockMvc.perform(post("/api/people") .contentType(TestUtil.APPLICATION_JSON_UTF8) .content(TestUtil.convertObjectToJsonBytes(person))) .andExpect(status().isCreated()); // Validate the Person in the database List<Person> personList = personRepository.findAll(); assertThat(personList).hasSize(databaseSizeBeforeCreate + 1); Person testPerson = personList.get(personList.size() - 1); assertThat(testPerson.getFirstName()).isEqualTo(DEFAULT_FIRST_NAME); assertThat(testPerson.getLastName()).isEqualTo(DEFAULT_LAST_NAME); assertThat(testPerson.getAge()).isEqualTo(DEFAULT_AGE); assertThat(testPerson.getCity()).isEqualTo(DEFAULT_CITY); }
jHipster가 생성 한 SpringBoot 프로젝트로 테스트했습니다.
-
==============================
3.
@RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = Application.class) public class SmokeTest { @Autowired UserController userController; @Autowired UserDao userDAO; @Rollback(false) // This is key to avoid rollback. @Test public void contextLoads() throws Exception { System.out.println("Hiren"); System.out.println("started"); userDAO.save(new User("tyx", "x@x.com")); } }
@Rollback (false)은 롤백을 피하기위한 키입니다.
-
==============================
4.엔티티 저장을위한 스프링은 트랜잭션이 필요합니다. 그러나 트랜잭션이 커밋 될 때까지 변경 사항은 다른 트랜잭션에서 볼 수 없습니다.
엔티티 저장을위한 스프링은 트랜잭션이 필요합니다. 그러나 트랜잭션이 커밋 될 때까지 변경 사항은 다른 트랜잭션에서 볼 수 없습니다.
가장 간단한 방법은 트랜잭션을 커밋 한 후 호출 컨트롤러입니다.
@Test @Transactional public void contextLoads() { Person person = personService.createPerson(1, "person1"); Assert.assertNotNull(person); TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() { @Override public void afterCommit() { ResponseEntity<Person[]> persons = restTemplate.getForEntity("/persons", Person[].class); } }); }
from https://stackoverflow.com/questions/43658630/spring-boot-test-transactional-not-saving by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] MockMVC 동일한 테스트 케이스에서 예외 및 응답 코드 테스트 방법 (0) | 2019.04.25 |
---|---|
[SPRING] 스프링 MVC에만 필요한 항아리는 무엇입니까? (0) | 2019.04.24 |
[SPRING] Flux <DataBuffer>의 압축을 해제하는 방법 (및 작성 방법) (0) | 2019.04.24 |
[SPRING] @DataJpaTest로 Spring 테스트는 @Repository로 클래스를 autowire 할 수 없습니다 (하지만 인터페이스 저장소가 작동합니다!). (0) | 2019.04.24 |
[SPRING] 도커가있는 스프링 부트가 요청 된 대상 오류에 대한 유효한 인증 경로를 찾을 수 없습니다. (0) | 2019.04.24 |