package jnpf.dmsService;
|
|
import jnpf.dmsEntity.wenjianbianhao.DmsFlowEventType;
|
import jnpf.dmsService.impl.DmsWenjianBianhaoApplicationServiceImpl;
|
import org.junit.jupiter.api.Test;
|
import org.springframework.aop.framework.ProxyFactory;
|
import org.springframework.dao.DuplicateKeyException;
|
import org.springframework.transaction.PlatformTransactionManager;
|
import org.springframework.transaction.TransactionDefinition;
|
import org.springframework.transaction.annotation.AnnotationTransactionAttributeSource;
|
import org.springframework.transaction.interceptor.TransactionInterceptor;
|
import org.springframework.transaction.support.SimpleTransactionStatus;
|
|
import static org.junit.jupiter.api.Assertions.*;
|
import static org.mockito.ArgumentMatchers.any;
|
import static org.mockito.Mockito.*;
|
|
class DmsWenjianBianhaoFlowServiceTest {
|
private final DmsWenjianBianhaoApplicationService applications = mock(DmsWenjianBianhaoApplicationService.class);
|
private final DmsWenjianBianhaoFlowService service = new DmsWenjianBianhaoFlowService(applications);
|
|
@Test
|
void successDoesNotMarkFailure() {
|
service.sync("flow", "task", 2, DmsFlowEventType.END);
|
verify(applications, never()).markIssuanceFailed(any(), any());
|
}
|
|
@Test
|
void failureIsMarkedAndOriginalErrorIsRethrown() {
|
var failure = new DuplicateKeyException("number already issued");
|
doThrow(failure).when(applications).syncApplicationFlow("flow", "task", 2, DmsFlowEventType.END);
|
assertSame(failure, assertThrows(DuplicateKeyException.class,
|
() -> service.sync("flow", "task", 2, DmsFlowEventType.END)));
|
var order = inOrder(applications);
|
order.verify(applications).syncApplicationFlow("flow", "task", 2, DmsFlowEventType.END);
|
order.verify(applications).markIssuanceFailed("flow", "task");
|
}
|
|
@Test
|
void nonIssuanceFailureDoesNotChangeRequestNumber() {
|
for (var event : DmsFlowEventType.values()) {
|
if (event == DmsFlowEventType.END) continue;
|
doThrow(new IllegalStateException("failed")).when(applications)
|
.syncApplicationFlow("flow", "task", 2, event);
|
assertThrows(IllegalStateException.class, () -> service.sync("flow", "task", 2, event));
|
}
|
doThrow(new IllegalStateException("failed")).when(applications)
|
.syncApplicationFlow("flow", "task", 1, DmsFlowEventType.END);
|
assertThrows(IllegalStateException.class, () -> service.sync("flow", "task", 1, DmsFlowEventType.END));
|
verify(applications, never()).markIssuanceFailed(any(), any());
|
}
|
|
@Test
|
void markingFailureDoesNotHideOriginalError() {
|
var original = new DuplicateKeyException("duplicate");
|
var marking = new IllegalStateException("database unavailable");
|
doThrow(original).when(applications).syncApplicationFlow("flow", "task", 2, DmsFlowEventType.END);
|
doThrow(marking).when(applications).markIssuanceFailed("flow", "task");
|
assertSame(original, assertThrows(DuplicateKeyException.class,
|
() -> service.sync("flow", "task", 2, DmsFlowEventType.END)));
|
assertArrayEquals(new Throwable[]{marking}, original.getSuppressed());
|
}
|
|
@Test
|
void springProxyRollsBackIssuanceBeforeStartingAndCommittingFailureMarker() {
|
var target = mock(DmsWenjianBianhaoApplicationServiceImpl.class);
|
var transactions = mock(PlatformTransactionManager.class);
|
var issuance = new SimpleTransactionStatus();
|
var marker = new SimpleTransactionStatus();
|
when(transactions.getTransaction(any())).thenReturn(issuance, marker);
|
var proxy = new ProxyFactory(target);
|
proxy.setInterfaces(DmsWenjianBianhaoApplicationService.class);
|
proxy.addAdvice(new TransactionInterceptor(transactions, new AnnotationTransactionAttributeSource()));
|
var flow = new DmsWenjianBianhaoFlowService((DmsWenjianBianhaoApplicationService) proxy.getProxy());
|
doThrow(new DuplicateKeyException("duplicate")).when(target)
|
.syncApplicationFlow("flow", "task", 2, DmsFlowEventType.END);
|
assertThrows(DuplicateKeyException.class, () -> flow.sync("flow", "task", 2, DmsFlowEventType.END));
|
var order = inOrder(transactions, target);
|
order.verify(transactions).getTransaction(argThat(d -> d.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRED));
|
order.verify(target).syncApplicationFlow("flow", "task", 2, DmsFlowEventType.END);
|
order.verify(transactions).rollback(issuance);
|
order.verify(transactions).getTransaction(argThat(d -> d.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW));
|
order.verify(target).markIssuanceFailed("flow", "task");
|
order.verify(transactions).commit(marker);
|
}
|
}
|