【发布时间】:2019-10-10 17:24:28
【问题描述】:
在我的 Spring 集成测试中(使用 JUnit 5。我的测试类注释为 @SpringBootTest(classes = {SecurityBeanOverrideConfiguration.class, XXXApp.class}),我试图在我的 @AfterEach 方法中调用 repository.deleteAll()。
查看日志中的SQL,好像什么都没执行;事实上,在接下来的测试中,无法创建具有相同 ID 的实体,因为它已经存在——这意味着某些东西阻止了数据库。正如其他问题所提到的,我使用过不同的事务类型(传播、隔离......),但无济于事。
不过,有趣的是,调用 repository.deleteAllInBatch() 而不是 deleteAll() 确实工作:所有测试都通过了。
发生了什么事?
编辑:添加代码。
@Transactional
@SpringBootTest(classes = {SecurityBeanOverrideConfiguration.class, XXXApp.class})
public class DeviceResourceIT {
@Autowired DeviceRepository deviceRepository;
@Autowired DeviceService lotService;
@Autowired private MappingJackson2HttpMessageConverter jacksonMessageConverter;
@Autowired private ExceptionTranslator exceptionTranslator;
private MockMvc mockMvc;
private Logger log = LoggerFactory.getLogger(DeviceResourceIT.class);
@PostConstruct
void setup() {
DeviceResource deviceResource = new DeviceResource(deviceService);
mockMvc = MockMvcBuilders.standaloneSetup(deviceResource)
.setControllerAdvice(exceptionTranslator)
.setConversionService(createFormattingConversionService())
.setMessageConverters(jacksonMessageConverter)
.build();
}
@Test
public void getLot() throws Exception
{
String lotID;
String wrongLotID = "aRandomString";
final List<DeviceRequestDTO> requests = Arrays.asList(
new DeviceRequestDTO("l1", "ble1"),
new DeviceRequestDTO("l2", "ble2"),
new DeviceRequestDTO("l3", "ble3")
);
LotDTO lotDTO = new LotDTO(requests);
MvcResult mvcResult = mockMvc.perform(post("/api/admin/lot")
.contentType(MediaType.APPLICATION_JSON)
.characterEncoding("utf-8")
.content(toJsonString(lotDTO)))
.andDo(print())
.andExpect(status().isOk())
.andReturn();
LotDTO returnedLotDTO = convertJsonBytes(mvcResult.getResponse().getContentAsByteArray(), LotDTO.class);
lotID = returnedLotDTO.getId();
log.info("{the lot id is : }" + lotID);
// retrieve the Lot with the right lot ID
mockMvc.perform(get("/api/admin/lot/{lot_id}", lotID))
.andDo(print())
.andExpect(status().isOk());
}
@AfterEach
public void tearDown() {
try {
log.info("{}", deviceRepository.count());
// Returns: 3
deviceRepository.deleteAll();
log.info("{}", deviceRepository.count());
// Returns: 3
// ... but we would expect to see 0, given the call to
// deleteAll() just above...
} catch (Exception e) {
Fail.fail(e.getMessage());
}
}
}
【问题讨论】:
-
一些代码会有所帮助。默认情况下,Spring 测试在每次测试后回滚事务,因此不需要显式删除先前测试插入的数据。
-
我会做一个最小的例子并尽快提供。
-
@AlanHay:请查看我刚刚进行的编辑。我参加了我的一门测试课程,只留下了一个测试用例并设置/拆除。关键注释在
tearDown中:清除存储库后,执行count()返回3,即使刚刚调用了deleteAll()。同样奇怪的是,如果我改为调用deleteAllInBatch(),输出是3, 0,正如我所料。
标签: hibernate spring-boot jpa spring-data-jpa junit5