简体   繁体   English

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

[英]Grails dynamic methods not present when running integration tests

I'm working on a project using Grails 2.5.4 and I'm currently trying to run some integration tests that are not running. 我正在使用Grails 2.5.4开发项目,目前正在尝试运行一些未运行的集成测试。 I've debugged the issue and found that apparently some dynamic methods on the services to be tested are not there when running in an integration test (if you run that in the context of the application the methods are there and everything works). 我已经调试了该问题,发现在集成测试中运行时显然没有要测试的服务上的某些动态方法(如果在应用程序的上下文中运行该方法,则所有方法都可以使用)。 This happens in many of the test I'm trying to run, I've choose one as an example but the others that are failing have the same problems. 在我尝试运行的许多测试中都会发生这种情况,我选择了其中的一个作为示例,但其他未通过的测试则存在相同的问题。

I have this domain class 我有这个领域课程

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

and a service method to be tested: 以及要测试的服务方法:

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

So then I run this spock test 所以我运行了这个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])
    ...
}

it fails in the line moveEvent.addToBundles(Bundle.get(id)) of BundleService with the following exception 它在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)

The problem is that the method addToBundles() that should be added dynamically by Grails to the Event class because of the hasMany collection "bundles" is not added. 问题在于由于没有hasMany集合“ bundles”,应由Grails动态将方法addToBundles()添加到Event类。 As I mentioned, if you run the application and use this service the method is there and everything works. 如前所述,如果您运行应用程序并使用此服务,则方法就存在,并且一切正常。

I tried changing the base class of the test (from Specification to IntegrationSpec) since I belive here is where the dynamic capabilities as well as transaction management and other things for integration tests are managed, but it didn't worked. 我尝试更改测试的基类(从Specification到IntegrationSpec),因为我相信这里是管理动态功能以及事务管理和其他用于集成测试的内容的地方,但是没有用。

Is there any reason why this method that should be there in the service is not present in the context of integration tests? 是否有任何理由为什么在集成测试的上下文中不存在应在服务中使用的此方法? Thanks 谢谢

You are missing grails.test.mixin.Mock annotation in your test class. 您在测试类中缺少grails.test.mixin.Mock批注。 Grails unit test uses this mixin to generate all domain related methods for a class so you can use this domain correctly in the unit test. Grails单元测试使用此mixin生成类的所有域相关方法,因此您可以在单元测试中正确使用此域。 Something like this should do the trick: 这样的事情应该可以解决问题:

@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])
    ...
}

More about testing domain classes can be found here: https://grails.github.io/grails2-doc/2.4.5/guide/testing.html#unitTestingDomains 有关测试域类的更多信息,请参见: https : //grails.github.io/grails2-doc/2.4.5/guide/testing.html#unitTestingDomains

@Szymon Stepniak Thanks for your answer, and sorry for the late reply. @Szymon Stepniak感谢您的回答,对于您的答复太晚表示抱歉。 I've tested what you proposed but it didn't work. 我已经测试了您的建议,但是没有用。 Later I've read that the grails.test.mixin.Mock annotation is only for unit tests, and it should not be used in integration tests. 稍后我读到grails.test.mixin.Mock批注仅用于单元测试,不应在集成测试中使用。 This is also true for @TestFor and @TestMixin annotations as well (I've read about this in this post ). @TestFor@TestMixin批注也是如此(我已经在这篇文章中阅读了此内容)。
So after this a collegue at work proposed me to search for this kind of annotations in other tests thinking that maybe that could lead to some kind of test pollution between tests, and after removing a @TestFor annotation in one of the tests that ran previously as part of the whole integration test suite, the failing test that I posted started working. 因此,在此之后,一个工作中的同事建议我在其他测试中搜索这种注释,以为这可能会导致测试之间的某种测试污染,并在先前运行的其中一个测试中删除了@TestFor注释后作为整个集成测试套件的一部分,我发布的失败测试开始起作用。 The strangest thing (appart from the compiler not complaining about this) is that the offending test (the one from which I removed the @TestFor annotation) was passing all green, it wasn't even failing! 最奇怪的事情(来自编译器的抱怨是没有抱怨的)是令人讨厌的测试(我从中删除了@TestFor批注的测试)全部通过了绿色测试,甚至没有失败!
So if someone has a similar problem I suggest to search for this kind of unit test annotations anywhere in the whole integration tests suite and remove it because the compiler won't complain, but in my experience it could have influence on other tests and it can lead to very strange behaviour. 因此,如果有人遇到类似的问题,我建议在整个集成测试套件中的任何位置搜索这种单元测试注释,并删除它,因为编译器不会抱怨,但是以我的经验,它可能会对其他测试产生影响,并且可以导致非常奇怪的行为。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM