如何在Java 8中测试“即发即弃”请求?

时间:2017-10-25 20:25:59

标签: java multithreading junit java.util.concurrent

我有这个代码,它是在我需要测试的另一个线程上运行的。

这是我的代码。

ExecutorService executor = Executors.newSingleThreadExecutor();
                executor.submit(() -> {
                    String partitionKey = format("partitionKey-%d", random.nextInt(10000));

                    String pPpageViewStreamName = this.stormConf.get(pPAGEVIEW_STREAMNAME).toString();
                    PutRecordResult putRecordResult = this.amazonKinesisClient.putRecord(pageViewStreamName,
                            wrap(gson.toJson(newMap).getBytes()),
                            partitionKey);

                    LOG.debug(format("Put Result in shardId %s with data %s: ", putRecordResult.getShardId(), newMap.toString()));
                });

但我的测试不会起作用。这是我的测试

FixtureGenerator fixtureGenerator = FixtureGenerator.create()。buildPageViewEvent();         元组元组= MockTupleHelpers.mockTuple(fixtureGenerator.toJson());

    when(this.random.nextInt(10000)).thenReturn(1000);

    PutRecordResult putRecordResult = new PutRecordResult();
    putRecordResult.setShardId("shardId");
    when(this.amazonKinesisClient.putRecord(any(String.class), any(ByteBuffer.class), any(String.class))).thenReturn(putRecordResult);

    bolt.execute(tuple, null);

    verify(this.amazonKinesisClient).putRecord(this.captorStreamName.capture(), this.captorData.capture(), this.captorPartitionKey.capture());

    assertThat(this.captorStreamName.getValue(), is(equalTo("pageview-ci")));
    assertThat(this.captorPartitionKey.getValue(), is(equalTo("partitionKey-1000")));

bolt.execute是解雇的代码。

我得到的错误就是这个

Wanted but not invoked:
amazonKinesisClient.putRecord(
    <Capturing argument>,
    <Capturing argument>,
    <Capturing argument>
);
-> at io.data.bolt.EmitPageViewBoltTest.shouldEmitDataToKinesis(EmitPageViewBoltTest.java:83)
Actually, there were zero interactions with this mock.

Wanted but not invoked:

这是因为永远不会调用amazonKinesisClient。我试过Thread.sleep(1000),但它也不起作用。

1 个答案:

答案 0 :(得分:0)

  1. 测试此方法的一种可能方法是使用ExecutorService工厂,该工厂可以在您的测试类中注入。对于测试设置,您可以使用使用当前线程的ExecutorService。这允许您的测试测试功能,就好像它不是多线程的一样。

  2. 另一种可能的方法是在单独的类中提取线程上的行为,并单独测试该类。

  3. 在某些情况下,不太理想,但可行,甚至是理想的是从周围的方法返回Future。在测试中,您可以在get()上调用Future并声明其返回值,并且没有发生异常。

  4. 对于您当前的代码,您在运行测试后立即进行验证。这会造成竞争条件。睡觉可以帮助,但你永远不会得到可靠的测试,这也很快。您可以将amazonKinesisClient.putRecord()存根在二进制countDown()上调用CountDownLatch,并在测试方法中等待锁存器超时,然后再进行验证。

    你说你已经尝试过睡觉了,并且该方法没有被调用。在调用方法之前可能会发生Exception。如果没有更多源代码,我无法告诉您Exception可能是什么。