【问题标题】:Grails dynamic methods not present when running integration tests运行集成测试时不存在 Grails 动态方法
【发布时间】:2018-09-25 19:06:07
【问题描述】:

我正在使用 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 动态添加到 Event 类的方法 addToBundles() 没有添加。正如我所提到的,如果您运行应用程序并使用此服务,方法就在那里,一切正常。

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

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

【问题讨论】:

    标签: grails integration-testing spock grails-2.5


    【解决方案1】:

    您的测试类中缺少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

    【讨论】:

      【解决方案2】:

      @Szymon Stepniak 感谢您的回答,很抱歉回复晚了。我已经测试了您提出的建议,但没有奏效。后来我读到 grails.test.mixin.Mock 注解仅用于单元测试,不应在集成测试中使用。 @TestFor@TestMixin 注释也是如此(我在 this post 中读到了这一点)。
      因此,在此之后,一位同事建议我在其他测试中搜索这种注释,认为这可能会导致测试之间出现某种测试污染,并且在之前运行的其中一个测试中删除了 @TestFor 注释之后作为整个集成测试套件的一部分,我发布的失败测试开始工作。最奇怪的事情(除了编译器没有抱怨这一点)是有问题的测试(我从中删除了@TestFor 注释的测试)通过了所有绿色,甚至没有失败!
      因此,如果有人有类似的问题,我建议在整个集成测试套件的任何地方搜索这种单元测试注释并将其删除,因为编译器不会抱怨,但根据我的经验,它可能会影响其他测试并且它可以导致非常奇怪的行为。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-04-13
        • 2011-07-11
        • 1970-01-01
        • 1970-01-01
        • 2018-06-14
        • 1970-01-01
        • 1970-01-01
        • 2023-03-31
        相关资源
        最近更新 更多