简体   繁体   English

Grails单元测试在@PostConstruct上失败

[英]Grails unit test fails on @PostConstruct

Have a @PostConstruct in the service to ensure that the dependencies have been set up. 服务中具有@PostConstruct ,以确保已建立依赖项。 Dependencies are set in resources.groovy . 依赖项在resources.groovy中设置。 Unit test fails on @PostConstruct asserts. @PostConstruct断言上的单元测试失败。 Tried setting up the dependencies manually in setUpSpec to no avail. 尝试在setUpSpec手动设置依赖项无效。 Even without a @TestFor , ServiceUnitTestMixin kicks in and merrily chokes on @PostConstruct . 即使没有@TestForServiceUnitTestMixin @TestFor@PostConstruct上出现并@TestFor Opened a defect GRAILS-11878 which was closed promptly with an advice to use @FreshRuntime and doWithSpring . 打开了缺陷GRAILS-11878 ,该缺陷立即关闭,并建议使用@FreshRuntimedoWithSpring If they actually bothered to try, they'd have gotten the following error: 如果他们真的不愿意尝试,他们将得到以下错误:

org.codehaus.groovy.runtime.typehandling.GroovyCastException: Cannot cast object 'grails.spring.BeanBuilder$ConfigurableRuntimeBeanReference$WrappedPropertyValue@2cce10bc' with class 'grails.spring.BeanBuilder$ConfigurableRuntimeBeanReference$WrappedPropertyValue' to class 'java.util.Collection' 

Service under test: 被测服务:

@Transactional
class MovieRipIndexService {

    Collection<String> genres

    Collection<String> includes

    @PostConstruct
    void postConstruct() {
        notEmpty(genres as Collection, 'Genres must not be null or empty.')
        notEmpty(includes as Collection, 'Includes must not be null or empty.')
    }
}

Test: 测试:

@FreshRuntime
@TestFor(MovieRipIndexService)
class MovieRipIndexServiceSpec extends Specification {

    def doWithSpring = {
        serviceHelper(ServiceHelper)

        service.genres = serviceHelper.genres
        service.includes = serviceHelper.includes
    }
}

Spring support in unit tests is rather minimal, and the ApplicationContext that's active doesn't really go through any of the lifecycle phases that it would in a running app, or even during initialization of integration tests. 单元测试中的Spring支持非常少,活动的ApplicationContext实际上并没有经历正在运行的应用程序甚至集成测试初始化​​期间的任何生命周期阶段。 You get a lot of functionality mixed into your class when using @TestFor and/or @Mock , but it's almost entirely faked out so you can focus on unit testing the class under test. 使用@TestFor和/或@Mock ,您的类中混入了很多功能,但是几乎完全被假冒了,因此您可以专注于对被测类进行单元测试。

I tried implementing org.springframework.beans.factory.InitializingBean just now and that worked, so you might get further with that. 我刚刚尝试实现org.springframework.beans.factory.InitializingBean并成功了,所以您可能会做得更好。 @Transactional will also be ignored - the "database" is a ConcurrentHashMap , so you wouldn't get far with that anyway. @Transactional也将被忽略-“数据库”是ConcurrentHashMap ,因此无论如何您都不会走得太远。

If you need real Spring behavior, use integration tests. 如果您需要真实的Spring行为,请使用集成测试。 Unit tests are fast and convenient but only useful for a fairly limited number of scenarios. 单元测试既快速又方便,但仅在相当有限的情况下有用。

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

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