【问题标题】:How do I test fire-and-forget request in Java 8?如何在 Java 8 中测试即发即弃请求?
【发布时间】:2018-04-07 01:52:36
【问题描述】:

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

这是我的代码。

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) 但它也不起作用。

【问题讨论】:

    标签: java multithreading junit java.util.concurrent


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

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

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

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

    您说您已经尝试过休眠,并且该方法没有被调用。可能在调用方法之前出现Exception。如果没有更多源代码,我无法告诉您该异常可能是什么。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多