如何正确测试这种定时并发处理服务?

How to properly test this kind of timed concurrent processing service?

我有一个用于模拟物联网硬件组件的服务,该组件定期向 SOAP 端点发送数据:

private static final int DEFAULT_CHUNK_SIZE_IN_BYTES = 100 * 1024;

public void simulate(final int samplingFrequencyMs, final int uploadFrequencyMs) {
    // ...

此方法在每次 samplingFrequencyMs 时间过去时生成一个 JSON 对象,并在每次 uploadFrequencyMs 时间过去时调用 SOAP 端点并将生成的数据分块为 DEFAULT_CHUNK_SIZE_IN_BYTES 大小大块。

例如,如果 samplingFrequencyMs500 并且 uploadFrequencyMs1000 那么这个方法将每秒发送 2 个生成的 JSON 字符串到 SOAP端点,如果 2 JSON 字符串的大小为 200 KB,则它将发送 2 个块。

还有一种停止模拟的方法:

public void stopSimulation() {
    // ...

我已经为这个模拟器写了一个测试:

@Test
public void shouldSendProperAmountOfChunksWhenInvokingSimulate() throws InterruptedException
{
    // ...

    // when
    underTest.simulate(100, 500);
    Thread.sleep(750);

    underTest.stopSimulation();

    Thread.sleep(500);

    // then
    verify(requestServiceMock, times(EXPECTED_REQUEST_CALL_TIMES)).doRequest(uploadBinary, header);
}

但是此测试在 100 次中有 1-2 次失败,因为该服务未被调用 EXPECTED_REQUEST_CALL_TIMES 次,因此它不稳定。当我必须验证调用方法的时间但涉及时间时,如何测试它?我使用 750 是因为它介于 5001000 之间,我认为这应该可以解决问题,但我认为对于这种情况必须有一些测试最佳实践。

您需要做的是从您的 CUT 中抽象出系统时间的概念。一种典型的方法是注入一个您可以控制的 Clock 对象。您的实际实现将委托给系统时钟,但在测试中您可以完全控制正在发生的事情。