Events 如何在Grails3.2中测试服务中事件的触发?

Events 如何在Grails3.2中测试服务中事件的触发?,events,grails,spock,Events,Grails,Spock,我运行在Grails3.2.5上,实现了一个简单的服务。该服务有一个私有方法和一个公共方法。private方法触发Events属性提供的EventBus的notify方法 @Transactional class SyncService { def processQueue() { checkStatus(true) } private checkStatus(status) { if(status) { def mo

我运行在Grails3.2.5上,实现了一个简单的服务。该服务有一个私有方法和一个公共方法。private方法触发Events属性提供的EventBus的notify方法

@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)

谢谢你的帮助

以下表达式:

1 * service.notify(_)
表示使用任何单个参数调用notify方法

试试这个:

1 * service.notify(*_)

PS:message调用太少之后是否还有其他信息?调用了什么的任何示例?

以下表达式:

1 * service.notify(_)
表示使用任何单个参数调用notify方法

试试这个:

1 * service.notify(*_)

PS:message调用太少之后是否还有其他信息?有什么调用的示例吗?

为了测试事件,我发现了一个变通方法。我没有检查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

    }
}

我发现了一个变通方法来测试事件。我没有检查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

    }
}

您可以模拟事件总线,并在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

  }
}

您可以模拟事件总线,并在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

  }
}

谢谢你的建议!我尝试过这个,但仍然收到相同的消息。是的,还有一个附加信息,说明processQueue方法已经被调用过一次。就这些。谢谢你的建议!我尝试过这个,但仍然收到相同的消息。是的,还有一个附加信息,说明processQueue方法已经被调用过一次。仅此而已。then子句是否应指定1*service.eventBus.notify*ɹ?此外,这似乎引发groovy.lang.ReadOnlyPropertyException异常。then子句是否应指定1*service.eventBus.notify*ɹ?此外,这似乎引发groovy.lang.ReadOnlyPropertyException异常。