春季开机测试@Transactional未保存
问题描述:
我试图使用Spring Boot Test进行简单的集成测试,以测试e2e用例。我的测试不起作用,因为我'不能使资源库保存的数据,我想我和春天有个上下文的问题...春季开机测试@Transactional未保存
这是我的实体:
@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);
}
}
测试不起作用,因为服务不保存Person实体.... 预先感谢
答
感谢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);
}
希望它能够帮助别人一天......感谢大家
答
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = Application.class)
public class SmokeTest {
@Rollback(false) //This is key to avoid rollback.
@Test
public void contexLoads() throws Exception {
System.out.println("Hiren");
System.out.println("started");
_userDAO.save(new User("tyx", "[email protected]"));
}
@Autowired
UserController userController;
@Autowired
UserDao _userDAO;
}
参考@Rollback(假)是关键,以避免回滚。
那当然不是......你的测试是事务性的,所以事务包装你的测试方法。所以之后会回滚(并且您的服务参与了该交易)。即使你使用'flush'也不行,因为你正在使用rest来访问会打开一个新事务的应用程序。使这项工作的唯一方法是使测试不是事务性的。 –
你可以尝试拆分你的测试。创建私有方法来保存具有事务注释的人并从测试方法中调用它。 – kimy82
正如@ M.Deinum所说,事务在您的测试中回滚,并且您看不到任何更改。尝试在测试中添加'@Commit'或@Rollback(false)。 – dev4Fun