Hed*_*yed 5 java spring spring-test spring-boot
我正在尝试使用Spring Boot Test做一个简单的集成测试,以测试e2e用例。我的测试无法正常工作,因为我无法使存储库保存数据,我认为我的Spring上下文有问题...
这是我的实体:
@Entity
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class Person {
@Id
private int id;
private String name;
}
Run Code Online (Sandbox Code Playgroud)
这是个人资料库:
@Repository
public interface PersonRepository extends JpaRepository<Person, Integer> {
}
Run Code Online (Sandbox Code Playgroud)
人员服务:
@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();
}
}
Run Code Online (Sandbox Code Playgroud)
人员控制器:
@RequestMapping
@RestController
public class PersonController {
@Autowired
private PersonService personService;
@RequestMapping("/persons")
public List<Person> getPersons() {
return personService.getPersons();
}
Run Code Online (Sandbox Code Playgroud)
}
主要的应用类:
@SpringBootApplication
public class BootIntegrationTestApplication {
public static void main(String[] args) {
SpringApplication.run(BootIntegrationTestApplication.class, args);
}
}
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
和测试:
@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);
}
}
Run Code Online (Sandbox Code Playgroud)
测试不起作用,因为该服务没有保存Person实体....预先感谢
use*_*406 12
@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"));
}
}
Run Code Online (Sandbox Code Playgroud)
参考@Rollback(false)是避免回滚的关键。
感谢 M. Deinum,我想我明白了,所以最好将测试的逻辑分成两个测试,第一个测试只测试服务(所以这个可以是事务性的),第二个测试控制器:
测试 1:
@Test
@Transactional
public void testServiceSaveAndRead() {
personService.createPerson(1, "person1");
Assert.assertTrue(personService.getPersons().size() == 1);
}
Run Code Online (Sandbox Code Playgroud)
测试 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);
}
Run Code Online (Sandbox Code Playgroud)
Spring保存实体需要事务。但在事务提交之前,其他事务中的更改是不可见的。
最简单的方法是在提交事务后调用控制器
@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);
}
});
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
11704 次 |
| 最近记录: |