I have a test method which sometimes fails during deploy and sometimes does not. I have never seen it fail on my local. You can see my code below.
I have the following retry mechanism which is asynchronously called from another service:
@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);
}
The notification service is like this :
@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");
}
}
And the commmon transactions service is like this :
@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;
}
Here is my integration test :
@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);
}
In the test method it is confirmed that updateNotificationOrderRetryCount
is called and the order status is updated as IN_PROGRESS
. However, the error message is null and I get the following assertion error :
-- failure 1 --
Expecting:
<null>
to be equal to:
<"ERROR">
but was not.
I expect saveNotificationOrderErrorMessage
transaction to be completed and the changes to be committed before updateNotificationOrderRetryCount
method is called. But it seems like it does work that way. Could anyone help me find out why my code behave like this ?
How can I reproduce this error on my local? And what can I do to fix it ?
Thanks.