스프링 부트 테스트 @ 트랜잭션이 저장되지 않음
저는 e2e 사용 사례를 테스트하기 위해 스프링 부트 테스트를 사용하여 간단한 통합 테스트를 하려고 합니다.데이터를 저장하는 저장소를 만들 수 없기 때문에 테스트가 작동하지 않습니다. 스프링 컨텍스트에 문제가 있는 것 같습니다.
내 엔티티입니다.
@Entity
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class Person {
@Id
private int id;
private String name;
}
사용자 저장소입니다.
@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);
}
}
서비스가 사용자 엔티티를 저장하지 않기 때문에 테스트가 작동하지 않습니다.잘 부탁드립니다.
@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)
롤백을 방지하는 데 중요합니다.
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);
}
엔티티를 저장하기 위한 스프링에는 트랜잭션이 필요합니다.그러나 트랜잭션이 커밋되기 전까지는 다른 트랜잭션에서 변경 사항을 볼 수 없습니다.
가장 간단한 방법은 커밋 트랜잭션 후 컨트롤러 호출
@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);
}
});
}
각각@Test
변경사항을 영구적으로 유지하려면 DB 트랜잭션을 수행하는 기능을 사용할 수 있습니다.@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 프로젝트를 사용하여 테스트했습니다.
- 스프링 부트: 1.5.4
- j유닛 4.12
- 봄 4.3.9
테스트가 실행되는 순서에 주의하십시오. @Commit 또는 @Rollback(false) 주석이 있는 테스트가 먼저 실행되어야 합니다. https://www.baeldung.com/junit-5-test-order
사용 안 함@Rollback(false)
단위 검정은 데이터를 생성하지 않아야 합니다.
JPA 플러시 모드는AUTO
(기본값 - 쿼리 발생 시 INSERT/UPDATE/DELETE SQL 플러시) /COMMIT
.
작업 엔티티에 FLASH를 강제로 적용하거나 EntityManager를 사용하여 강제로 플러시하도록 쿼리하기만 하면 됩니다.
@Test
public void testCreate(){
InvoiceRange range = service.createInvoiceRange(1, InvoiceRangeCreate.builder()
.form("01GTKT0/010")
.serial("NV/18E")
.effectiveDate(LocalDate.now())
.rangeFrom(1L)
.rangeTo(1000L)
.build(), new byte[] {1,2,3,4,5});
service.findByCriteria(1, "01GTKT0/010", "NV/18E"); // force flush
// em.flush(); // another way is using entityManager for force flush
}
언급URL : https://stackoverflow.com/questions/43658630/spring-boot-test-transactional-not-saving
'programing' 카테고리의 다른 글
문자열에 숫자만 포함되어 있는지 python에서 어떻게 확인합니까? (0) | 2023.06.19 |
---|---|
PostgreSQL 인덱스 사용 분석 (0) | 2023.06.19 |
원격 Git 저장소에서 특정 커밋 검색 (0) | 2023.06.19 |
화면 업데이트의 효과 (0) | 2023.06.19 |
확인하지 못했습니다. com.google.파이어베이스:파이어베이스 코어:9.0.0 (0) | 2023.06.19 |