Java/Mockito - 线程在重试之前以指数方式 hibernate 的单元测试

标签 java spring unit-testing junit mockito

我正在尝试创建一个单元测试类来测试我创建的类。此类尝试发送消息,如果发送失败,它将以指数方式等待(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/

相关文章:

java - 为什么 IntelliJ 在使用本地数据源时找不到数据库用户凭据?

java - 安装SDX 麻烦org.apache.cocoon.ResourceNotFoundException : No pipeline matched request: index. html

java - 如何按类别查找书籍?

java - 严重 : The RuntimeException could not be mapped to a response, 重新抛出到 HTTP 容器 java.lang.NullPointerException

java - Apache DefaultHttpClient 调用结果为 "java.lang.RuntimeException: Stub!"

java - 如何在面板上绘制分隔符 (GridBagLayout)

java - 为什么Java和C#不允许在栈上创建对象?

mysql - Spring Hibernate 无法在初始化数据库时添加外键约束

unit-testing - Delphi XE2 中的重复构造函数警告

python - 如何在没有 Mock 的情况下 stub Python 方法