我正在尝试创建一个单元测试类来测试我创建的类。此类尝试发送消息,如果发送失败,它将以指数方式等待(1 秒、2 秒、4 秒、8 秒等),然后再重试发送消息。我想测试这种指数等待行为是否正常工作。但我对单元测试很陌生,不太确定如何使用 JUnit 和 Mockito 进行测试。任何帮助将不胜感激!
@Slf4j
@Setter
@RequiredArgsConstructor
@AllArgsConstructor(access = AccessLevel.PACKAGE)
public class RetriableProcessorExponentialDecorator implements
AbsMessageProcessorDecorator {
private final AbsMessageProcessor messageProcessor;
@Autowired
private AbsMessageActiveMQConfiguration configuration;
@Override
public void onMessage(AbsMessage message) throws Exception {
int executionCounter = 0;
long delay = 1000;
final int maxRetries = this.configuration.getExceptionRetry() + 1;
do {
executionCounter++;
try {
this.messageProcessor.onMessage(message);
} catch (RetriableException e) {
log.info("Failed to process message. Retry #{}", executionCounter);
delay = (long) (delay * (Math.pow(this.configuration.getMultiplier(), executionCounter)));
Thread.sleep(delay);
} catch (Exception e) {
// We don't retry on this, only RetriableException.
throw e;
}
} while (executionCounter < maxRetries && delay < Long.MAX_VALUE);
}
}
P.S 根据@Andy Turner的建议,我在我的RetriableProcessorExponentialDecorator类中添加了一行private final DefaultSleeper defaultSleeper;
,然后替换Thread.sleep(delay )
和 defaultSleeper.sleep(delay)
。
然后在我的单元测试类中,我通过执行 @Mock 来模拟 DefaultSleeper
private DefaultSleeper sleeper;
并通过 RetriableProcessorExponentialDecorator 的构造函数传递模拟对象,如下所示:
@Before
public void setUp() {
this.decorator = new
RetriableProcessorExponentialDecorator(sleeper, processor,
configuration);
}
我走在正确的道路上吗?
最佳答案
创建一个像这样的界面:
interface Sleeper {
void sleep(long delay) throws InterruptedException;
}
然后您可以创建一个实现:
class DefaultSleeper implements Sleeper {
@Override public void sleep(long delay) throws InterruptedException {
Thread.sleep(delay);
}
}
并模拟它:Sleeper sleeper = mock(Sleeper.class);
.
现在,您可以将其实例注入(inject)到您的 RetriableProcessorExponentialDecorator
中,并在测试中测试与模拟的交互。
关于Java/Mockito - 线程在重试之前以指数方式 hibernate 的单元测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54562426/