1

我正在使用 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),因为我相信这里是管理动态功能以及事务管理和其他用于集成测试的东西的地方,但它没有奏效。

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

4

2 回答 2

0

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

于 2018-10-23T13:28:25.463 回答
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

于 2018-09-25T19:13:55.927 回答