在测试兔子消费者时,如何在 micronaut 中使用 spock 来模拟服务?

ada*_*ack 7 rabbitmq spock micronaut micronaut-rabbitmq

我目前正在与:

  • 麦克诺3.7.3
  • RabbitMQ 3.11.2
  • 斯波克
  • Groovy / Java 17

我正在按照 micronaut 项目( https://micronaut-projects.github.io/micronaut-rabbitmq/3.1.0/guide/index.html)的指南为一个简单的演示项目实现一个rabbitmq消费者。

我正在尝试模拟一个服务,该服务是我的rabbitmq 消费者的依赖项。

我尝试过这种方法似乎不起作用:

@MicronautTest
@Subject(SampleRequestConsumer)
class SampleRequestConsumerSpec extends Specification {

    @Inject
    ExternalWorkflowProducer externalWorkflowProducer

    @Inject
    SampleRequestConsumer sampleRequestConsumer

    @Inject
    SimpleService simpleService

    @MockBean(SimpleService)
    SimpleService simpleService() {
        Mock(SimpleService)
    }


    def "It receives a sampleRequest message in the simple.request queue"() {
        when:
        externalWorkflowProducer.send(new SampleRequest(message: "Request1"))

        then:
        sleep(100)

        1 * simpleService.handleSimpleRequest(_ as SampleRequest) >> { SampleRequest request ->
            assert request.message != null
        }
    }

}
Run Code Online (Sandbox Code Playgroud)

运行集成测试时出现此错误:

Too few invocations for:

1 * simpleService.handleSimpleRequest(_ as SampleRequest) >> { SampleRequest request ->
            assert request.message != null
        }   (0 invocations)

Unmatched invocations (ordered by similarity):

None
Run Code Online (Sandbox Code Playgroud)

查看 GitHub 上的完整源代码:https://github.com/art-dambrine/micronaut-rabbitmq-spock-mocking/blob/test-with-mq/src/test/groovy/com/company/microproject/amqp/consumer /SampleRequestConsumerSpec.groovy

另请注意,当我不从队列中读取并直接调用正在运行的方法sampleRequestConsumer.receive([message: "Request1"]) 模拟时simpleServicehttps://github.com/art-dambrine/micronaut-rabbitmq-spock-mocking/blob/test-without-mq /src/test/groovy/com/company/microproject/amqp/consumer/SampleRequestConsumerSpec.groovy

预先感谢您的见解

重要的

请使用分行test-with-mq。该分支test-without-mq的测试将会成功,因为它没有使用rabbitMQ。这是试图证明问题在于测试 RabbitMQ 消费者。

Lui*_*ñiz 2

sleep()指令移至when:块修复了测试。

事实上,块后面的内容then:并不是在 后执行的externalWorkflowProducer.send(),而是由 Spock之前执行的。该指令:

1 * simpleService.handleSimpleRequest(_ as SampleRequest)
Run Code Online (Sandbox Code Playgroud)

正在功能方法范围内创建交互,并在配置规范时执行。

在那里添加sleep()指令,不会为消费者留下接收消息的规范时间。您需要sleep()在 后面添加send(). 这是您的测试需要让消费者有时间执行的时候。

注意:闭包本身:

 { SampleRequest request ->
            assert request.message != null
 }
Run Code Online (Sandbox Code Playgroud)

之后会执行,但只是关闭。配置 Spec 时已执行睡眠指令。在这种情况下,闭包不会执行,因为测试在使用者的线程可以调用模拟之前完成。

总之:

这有效:

    def "It receives a sampleRequest message in the simple.request queue"() {
        when:
        externalWorkflowProducer.send(new SampleRequest(message: "Request1"))
        sleep(100)

        then:
        1 * simpleService.handleSimpleRequest(_ as SampleRequest) >> { SampleRequest request ->
            assert request.message != null
        }
    }
Run Code Online (Sandbox Code Playgroud)

这不起作用:

    def "It receives a sampleRequest message in the simple.request queue"() {
        when:
        externalWorkflowProducer.send(new SampleRequest(message: "Request1"))

        then:
        sleep(100)
        1 * simpleService.handleSimpleRequest(_ as SampleRequest) >> { SampleRequest request ->
            assert request.message != null
        }
    }
Run Code Online (Sandbox Code Playgroud)