【发布时间】:2015-06-05 12:56:00
【问题描述】:
我有一项服务,用于模拟 IoT 硬件组件,该组件定期将数据发送到 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 大小的块。
例如,如果samplingFrequencyMs 是500 并且uploadFrequencyMs 是1000,那么此方法将每秒向 SOAP 端点发送 2 个生成的 JSON 字符串,如果 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,因为它介于500 和1000 之间,我认为这应该可以解决问题,但我认为对于这种情况必须有一些测试最佳实践。
【问题讨论】:
-
我假设在模拟方法中运行着生产者和消费者线程。如果消费者睡眠 1 秒,然后收集所有数据并发送到肥皂端点,而生产者在 0.5 秒内按顺序将数据插入队列中:我们可以预期消费者只会发送 1 件的条件。调用 Thread.sleep(500) 保证最少 500 毫秒的睡眠持续时间。它最终可能会等待超过 500 毫秒。
-
有一个
Timer,它每500毫秒调度一个生产者和一个消费者任务到Executor。
标签: java junit testng mockito timing