- @Sql at test class
INSERT INTO bankdemo.bills(id, is_active, balance, currency, account_id)
VALUES('0', '1', '0.00', 'RUB', '0');
- 绿色测试显示id == 0的Bill存在于DB
@Test
void can_change_bill_status() throws Exception {
mockMVC.perform(get("/bills/status/{id}", "0"))
.andExpect(status().isOk())
.andExpect(content().string(containsString("false")));
}
- 但下一个突然失败
@Test
void can_export_data_2_csv_file() throws Exception {
mockMVC.perform(get("/operations/print/{id}", "0"))
.andExpect(status().isCreated())
.andExpect(content().contentType(MediaType.APPLICATION_OCTET_STREAM_VALUE));
}
with CompletionException: EntityNotFoundException: id: 0的目标账单没有找到
使用ThreadPoolTaskExecutor从DB获取Bill的内部控制器方法
CompletableFuture<BillResponseDTO> futureBill = CompletableFuture.supplyAsync
(() -> {try {return billService.getBillDTO(id);}
catch(EntityNotFoundException exc) {log.error(exc.getMessage(), exc);
throw new CompletionException(exc);}
}, executorService);
BillResponseDTO bill = futureBill.join();
可能是这种情况,但如何正确测试这部分代码?
程序本身和切片@WebMvcTest使用模拟访问DB是好的。Spring Boot 2.6.6
添加:
@Bean
@Primary
public Executor asyncExecutor() {
final int cores = Runtime.getRuntime().availableProcessors();
final ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(cores);
executor.setMaxPoolSize(cores * 2);
executor.setQueueCapacity(cores * 10);
executor.initialize();
return executor;
}
还有另一个任务在这个特定的控制器方法异步运行,它根本不会引起任何问题:
CompletableFuture<List<OperationResponseDTO>> futureOperations =
CompletableFuture.supplyAsync(() -> operationService.getAll(id), executorService);
Ok,所以问题不是关于CompletableFuture,而是使用H2数据库的Spring Boot测试的行为。SQL脚本会奇怪地初始化数据,这取决于它们在哪个阶段被调用(在启动期间或通过测试类或方法声明上面的@SQL)。