【发布时间】:2021-02-05 19:05:58
【问题描述】:
我有一个测试方法,在部署过程中有时会失败,有时不会。我从未见过它在我的本地失败。你可以在下面看到我的代码。
我有以下从另一个服务异步调用的重试机制:
@Transactional
public boolean retry(NotificationOrder order) {
notificationService.send(order);
return true;
}
public void resolveOnFailedAttempt(Long orderId) { //automatically called if `retry` method fails
notificationOrderCommonTransactionsService.updateNotificationOrderRetryCount(orderId);
}
通知服务是这样的:
@Service
@RequiredArgsConstructor
public class NotificationServiceImpl implements NotificationService {
private final NotificationOrderCommonTransactionsService notificationOrderCommonTransactionsService;
@Override
@Transactional
public NotificationResponse send(NotificationOrder order) {
NotificationRequest request;
try {
request = prepareNotificationRequest(order);
} catch (Exception e) {
notificationOrderCommonTransactionsService.saveNotificationOrderErrorMessage(order.getId(),
e.getMessage());
throw e;
}
...
return response;
}
private void prepareNotificationRequest(NotificationOrder order) {
...
throw new Exception("ERROR");
}
}
而常见的交易服务是这样的:
@Transactional(propagation = Propagation.REQUIRES_NEW)
public NotificationOrder saveNotificationOrderErrorMessage(Long orderId, String errorMessage) {
NotificationOrder order = notificationRepository.findOne(orderId);
order.setErrorDescription(errorMessage);
notificationRepository.save(order);
return order;
}
public NotificationOrder updateNotificationOrderRetryCount(Long orderId) {
NotificationOrder order = notificationRepository.findOne(orderId);
order.setRetryCount(order.getRetryCount() + 1);
order.setOrderStatus(NotificationOrderStatus.IN_PROGRESS);
notificationRepository.save(order);
return order;
}
这是我的集成测试:
@Test
public void test() {
NotificationOrderRequest invalidRequest = invalidRequest();
ResponseEntity<NotificationOrderResponse> responseEntity = send(invalidRequest);
NotificationOrder notificationOrder = notificationOrderRepository.findOne(1);
softly.assertThat(notificationOrder.getOrderStatus().isEqualTo(NotificationOrderStatus.IN_PROGRESS))
softly.assertThat(notificationOrder.getErrorDescription())
.isEqualTo("ERROR"); //This the line that fails.
softly.assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.OK);
}
在测试方法中确认调用updateNotificationOrderRetryCount,订单状态更新为IN_PROGRESS。但是,错误消息为空,我收到以下断言错误:
-- failure 1 --
Expecting:
<null>
to be equal to:
<"ERROR">
but was not.
我希望saveNotificationOrderErrorMessage 事务完成并且在调用updateNotificationOrderRetryCount 方法之前提交更改。但它似乎确实是这样工作的。谁能帮我找出我的代码为什么会这样?
如何在本地重现此错误?我能做些什么来解决它?
谢谢。
【问题讨论】:
-
您实际上在
prepareNotificationRequestansend方法中抛出了什么样的异常。是RuntimeException吗?它没有在方法签名中声明。 -
我抛出了一个扩展
RuntimeException的类的异常。 -
是否可以假设通知订单的 id 始终为 1?是否有其他测试使用相同的存储库?您的测试数据存储的生命周期是什么?
标签: java spring hibernate transactions assertj