如何在Grails 3.2中测试服务中事件的触发?

时间:2017-02-13 23:35:56

标签: events grails spock

我在Grails 3.2.5上运行并实现了一项简单的服务。该服务有私人和公共方法。 private方法触发EventBus的notify方法(由Events trait提供)。

@Transactional
class SyncService {
    def processQueue() {
        checkStatus(true)
    }

    private checkStatus(status) {
       if(status) {
           def model = [...]
           notify "status.completed", model
       }
    }
}

如何为此服务编写单元测试,以检查通知是否已被触发?以下实现不起作用:

@TestFor(SyncService)
class SyncServiceSpec extends Specification {

    void "test if notification is triggerd() {
        when:
            service.processQueue()

        then: "notification should be triggered"
            1 * service.notify(_)

    }
}

测试失败,输出如下:

Too few invocations for:

1 * service.notify(_)   (0 invocations)

感谢您的帮助!

3 个答案:

答案 0 :(得分:2)

您可以模拟事件总线并在模拟上执行交互测试(在3.2.11中测试)

@TestFor(SyncService)
class SyncServiceSpec extends Specification {

  void 'test if notification is triggered'() {
    given: 'a mocked event bus'
    EventBus eventBusMock = Mock(EventBus)
    service.eventBus = eventBusMock

    when:
    service.processQueue()

    then: 'event bus is notified once'
    1 * eventBusMock.notify(*_)  //<--- you could get more specific with your arguments if you want

  }
}

答案 1 :(得分:1)

以下表达式:

1 * service.notify(_)

表示使用任何单个参数单次调用 notify 方法。

试试这个:

1 * service.notify(*_)

PS在“Too few invocations for:”消息之后是否有任何其他信息?有关已调用内容的任何示例吗?

答案 2 :(得分:1)

我发现了一种解决方法,以便测试该事件。我没有检查是否触发了notify方法,而是测试是否使用on方法触发了事件。因此,在我的测试课中,我有类似的东西:

@TestFor(SyncService)
class SyncServiceSpec extends Specification {

    void "test if notification is triggerd() {
        when:
            def eventResponse = null
            service.processQueue()
            service.on('status.completed') { data ->
                eventResponse = data
            }


        then: "notification should be triggered"
            eventResponse != null

    }
}