Quartz 集成测试和交易
Quartz Integration test and transactions
我尝试在 Quartz 调度程序上创建集成测试。
我有 2 个表:events 和 tasks。计划程序通过 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())
);
}
首先,我得到异常:
could not initialize proxy - no Session
我使用这个答案 并添加 spring.jpa.properties.hibernate.enable_lazy_load_no_trans=true
到我的测试配置。
所以现在我遇到了另一个问题 - 我的测试有时是正确的,但更多时候它失败了,因为它只创建 1 task.
方法,由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();
}
那么如何使用 Quarts 和事务正确创建集成测试?
测试class使用存储库的findAll方法,如果你尝试获取LAZY初始化方法,你会得到这个异常。
在断言中:
t.getEvent().getEventType() // can throw it
actual.get(0).getEvent() // can throw it
为了避免这种情况,您可以将其设为事务性或优先获取类型。
在 REPEATABLE READ 下,第二个 SELECT 保证至少显示从第一个 SELECT 返回的未更改的行。在那一分钟内,并发事务可能会添加新行,但无法删除或更改现有行。
Difference between "read commited" and "repeatable read"
我尝试在 Quartz 调度程序上创建集成测试。
我有 2 个表:events 和 tasks。计划程序通过 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())
);
}
首先,我得到异常:
could not initialize proxy - no Session
我使用这个答案 spring.jpa.properties.hibernate.enable_lazy_load_no_trans=true
到我的测试配置。
所以现在我遇到了另一个问题 - 我的测试有时是正确的,但更多时候它失败了,因为它只创建 1 task.
方法,由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();
}
那么如何使用 Quarts 和事务正确创建集成测试?
测试class使用存储库的findAll方法,如果你尝试获取LAZY初始化方法,你会得到这个异常。
在断言中:
t.getEvent().getEventType() // can throw it
actual.get(0).getEvent() // can throw it
为了避免这种情况,您可以将其设为事务性或优先获取类型。
在 REPEATABLE READ 下,第二个 SELECT 保证至少显示从第一个 SELECT 返回的未更改的行。在那一分钟内,并发事务可能会添加新行,但无法删除或更改现有行。
Difference between "read commited" and "repeatable read"