运行集成测试时不存在Grails动态方法

时间:2018-09-25 19:06:07

标签: grails integration-testing spock grails-2.5

我正在使用Grails 2.5.4进行项目,并且当前正在尝试运行一些未运行的集成测试。 我已经调试了该问题,发现在集成测试中运行时显然没有要测试的服务上的某些动态方法(如果在应用程序的上下文中运行该方法,则所有方法都可以使用)。在我尝试运行的许多测试中都会发生这种情况,我选择了其中一个作为示例,但其他失败的也有相同的问题。

我有这个域类

class Event {
...
    static hasMany = [
        bundles : Bundle
    ]
...    
}

和要测试的服务方法:

@Transactional
class BundleService {
...
    void assignEvent(Event event, List bundleIds) {
    ..
        for (id in bundleIds) {
            event.addToBundles(Bundle.get(id))
        }
    }
...
}

然后我运行这个spock测试

class BundleServiceIntegrationSpec extends Specification {

    BundleService bundleService
    EventService  eventService
    private BundleTestHelper bundleHelper = new BundleTestHelper()

    ...

    void '04. Test deleteBundleAndAssets method'() {
    when: 'a new Bundle is created'
        Bundle bundle = bundleHelper.createBundle(project, 'Test Bundle')
    and: 'a new Event is created'
        Event event = eventService.create(project, 'Test Event')
    and: 'the above Bundle is assigned to the Event'
        bundleService.assignEvent(event, [bundle.id])
    ...
}

在BundleService的 moveEvent.addToBundles(Bundle.get(id))行中失败,但有以下例外情况

groovy.lang.MissingMethodException: No signature of method: 
net.domain.Event.addToBundles() is applicable for argument 
types: (net.domain.Bundle) values: [Test Bundle]
Possible solutions: getBundles()
at net.service.BundleService.$tt__assignEvent(BundleService.groovy:101)

问题在于,由于hasMany集合“ bundles”,Grails应将动态添加的方法addToBundles()添加到Event类。正如我提到的,如果您运行应用程序并使用此服务,则该方法已存在,并且一切正常。

我尝试更改测试的基类(从Specification到IntegrationSpec),因为我相信这里是管理动态功能以及事务管理和其他用于集成测试的内容的地方,但是没有用。

是否有任何理由为什么在集成测试的上下文中不存在应在服务中使用的此方法?谢谢

2 个答案:

答案 0 :(得分:0)

您在测试课程中缺少grails.test.mixin.Mock批注。 Grails单元测试使用此mixin生成类的所有域相关方法,因此您可以在单元测试中正确使用此域。这样的事情应该可以解决问题:

@Mock([Event])
class BundleServiceIntegrationSpec extends Specification {

    BundleService bundleService
    EventService  eventService
    private BundleTestHelper bundleHelper = new BundleTestHelper()

    ...

    void '04. Test deleteBundleAndAssets method'() {
    when: 'a new Bundle is created'
        Bundle bundle = bundleHelper.createBundle(project, 'Test Bundle')
    and: 'a new Event is created'
        Event event = eventService.create(project, 'Test Event')
    and: 'the above Bundle is assigned to the Event'
        bundleService.assignEvent(event, [bundle.id])
    ...
}
  

有关测试域类的更多信息,请参见:https://grails.github.io/grails2-doc/2.4.5/guide/testing.html#unitTestingDomains

答案 1 :(得分:0)

@Szymon Stepniak ,谢谢您的回答,对于深信不清,我们深表歉意。我已经测试了您的建议,但是没有用。后来我读到  grails.test.mixin.Mock批注仅用于单元测试,不应在集成测试中使用。 @TestFor@TestMixin注释也是如此(我已经在this post中对此进行了了解)。
因此,在此之后,一位同事建议我在其他测试中搜索这种注释,以为这可能会导致测试之间的某种测试污染,并且在其中一项测试中删除了@TestFor注释后,之前作为整个集成测试套件的一部分运行,我发布的失败测试开始起作用。最奇怪的事情(来自编译器的抱怨是,没有抱怨)是令人讨厌的测试(我从中删除了@TestFor批注的测试)全部通过了绿色测试,甚至没有失败!
因此,如果有人遇到类似的问题,我建议在整个集成测试套件中的任何位置搜索这种单元测试注释,并删除它,因为编译器不会抱怨,但是以我的经验,它可能会对其他测试产生影响,并且可以导致非常奇怪的行为。