【问题标题】:Is it possible to have write NonBlocking Junit tests是否可以编写非阻塞 Junit 测试
【发布时间】:2014-04-09 20:07:02
【问题描述】:

我正在为 Amqp 消息侦听器编写一个 Junit 测试。这就是测试的编写方式。我向交换器发送一条消息并引入 1 秒的延迟(假设侦听器将在该时间范围内完成其工作)。这种方法减慢了构建过程,因为有 15-20 个这样的测试至少需要 20 秒才能执行。有没有一种方法可以让我做到这一点,这是一种非阻塞方式。通过一个调用处理程序来验证测试在侦听器完成工作之后。可能会在内部使用诸如 Actors 之类的东西

【问题讨论】:

    标签: java unit-testing testing junit integration-testing


    【解决方案1】:

    虽然不是“非阻塞”单元测试,但您可以使用 Awaitility 在 JUnit 中创建轮询间隔和最大等待时间。对于依赖异步结果的测试非常有用。

    您可以将轮询时间设置为较小的值,例如 10 英里和最长持续时间。每 10 毫秒,您评估某些条件的方法将被触发。它将继续被调用,直到条件返回 true,或者达到允许的最长时间。届时它将引发异常,导致单元测试失败。

    http://code.google.com/p/awaitility/

    【讨论】:

    • 但是测试仍然会阻塞直到最大等待时间对吗?
    • 只有在他们没有早点回来的情况下。这个想法是在异步进程上等待验证测试所需的最短时间。如果异步调用花费了允许的最长时间,它将抛出异常并且测试将失败。所以是的,从技术上讲不是非阻塞单元测试,而是比等待固定时间更好的方法。
    【解决方案2】:

    另一种方法是让处理程序在它们自己的线程中运行,就像它们在您的 amqp-client 中一样,并简单地阻塞主测试线程,直到预期的消息被消耗或测试超时。我们可以使用ConcurrentUnit 来做到这一点。示例,使用 amqp-client 库和 ConcurrentUnit:

    final Waiter waiter = new Waiter();
    int consumerCount = 5;
    
    // Start consumers
    for (int i = 0; i < consumerCount; i++) {
      channel.basicConsume(queueName, true, "myConsumerTag",
        new DefaultConsumer(channel) {
         public void handleDelivery(String consumerTag,
                                    Envelope envelope,
                                    AMQP.BasicProperties properties,
                                    byte[] body) throws IOException {
            String message = new String(delivery.getBody());
            if (message.equals(expectedMessage))
              waiter.resume();
         }
      });
    }
    
    waiter.await(10000, consumerCount);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-12
      • 2013-04-23
      • 2012-11-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多