我尝试在Quartz调度程序上创建集成测试。
我有两个表:事件和任务。调度程序通过cron触发器按事件创建任务。
@SneakyThrows
@Test
public void taskGenerationBeanTest() {
RequestData request = requestBuilder(str(), str(), str()).build();
String orderId = String.valueOf(UUID.randomUUID());
Event event1 = getEvent("type1", request, orderId);
Event event2 = getEvent("type2", request, orderId);
eventRepository.save(event1);
eventRepository.save(event2);
Thread.sleep(20000);
List<Event> events = eventRepository.findAll();
Thread.sleep(1000);
List<Task> actual = taskRepository.findAll();
assertAll(
() -> assertEquals(2, actual.size()),
() -> assertTrue(actual.stream().anyMatch(t ->
"type1".equals(t.getEvent().getEventType()))),
() -> assertEquals(event1.getOrderId(), actual.get(0).getEvent().getOrderId())
);
}
首先,我得到例外:
无法初始化代理-没有会话
我在Spring Data JPA中使用这个答案-“无法初始化代理-没有会话”-方法标记为事务性,并添加Spring.JPA.properties.hibernate。enable_lazy_load_no_trans=true
到我的测试配置。所以现在我又遇到了另一个问题——我的测试有时是正确的,但更常见的是它失败了,因为它只创建了一个任务。
由Quartz执行的方法:
@Override
@Transactional(isolation = Isolation.REPEATABLE_READ)
public int createAndSaveTasks(EventType eventType) {
List<Task> tasks = eventService.getEvent(eventType)
.stream()
.map(Task::new)
.collect(Collectors.toList());
taskRepository.saveAll(tasks);
return tasks.size();
}
那么,如何正确地使用Quart和事务创建集成测试呢?
测试类使用存储库的findAll方法,如果你试图得到懒惰的初始化方法,你会得到这个异常。
在断言中:
t.getEvent().getEventType() // can throw it
actual.get(0).getEvent() // can throw it
为了避免它,也许您可以将其设为事务性或急切获取类型。
在REPEATABLE READ下,第二个SELECT保证至少显示从第一个SELECT返回的行不变。在那一分钟内,并发事务可以添加新行,但不能删除或更改现有行。
“已提交读取”和“可重复读取”之间的差异