Grails单元测试在@PostConstruct上失败 [英] Grails unit test fails on @PostConstruct

查看:292
本文介绍了Grails单元测试在@PostConstruct上失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在服务中设置 @PostConstruct ,以确保依赖关系已被设置。依赖关系在 resources.groovy 中设置。 @PostConstruct 断言单元测试失败。尝试在 setUpSpec 中手动设置依赖关系无效。即使没有一个 @TestFor ServiceUnitTestMixin 也可以在 @PostConstruct
打开缺陷 GRAILS-11878 ,并立即关闭,并提供使用建议 @FreshRuntime doWithSpring 。如果他们真的很想尝试,他们会收到以下错误:

  org.codehaus.groovy.runtime.typehandling。 GroovyCastException:不能将类'grails.spring.BeanBuilder$ConfigurableRuntimeBeanReference$WrappedPropertyValue@2cce10bc'与类'grails.spring.BeanBuilder $ ConfigurableRuntimeBeanReference $ WrappedPropertyValue'转换为类'java.util.Collection'

被测服务

  @Transactional 
class MovieRipIndexService {

集合< String>流派

集合< String>包括

@PostConstruct
void postConstruct(){
notEmpty(类型为Collection,'类型不能为空或空)'
notEmpty(包括作为集合,'包含不能为null或空。'
}
}

测试:

  @FreshRuntime 
@TestFor(MovieRipIndexService)
class MovieRipIndexServiceSpec扩展规范{

def doWithSpring = {
serviceHelper(ServiceHelper)

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


解决方案

单元测试中的弹簧支持相当微乎其微,并且活动的 ApplicationContext 并不会真正影响到正在运行的应用程序中的任何生命周期阶段,甚至在初始化集成测试期间。使用 @TestFor 和/或 @Mock 时,您可以将很多功能混合到您的课堂中,但几乎完全是我们尝试实现 org.springframework.beans.factory.InitializingBean

c $ c>刚刚起作用,所以你可能会更进一步。 @Transactional 也将被忽略 - 数据库是一个 ConcurrentHashMap ,所以你不会那么远。



如果您需要真正的Spring行为,请使用集成测试。单元测试是快速和方便的,但只对相当有限的情况有用。


Have a @PostConstruct in the service to ensure that the dependencies have been set up. Dependencies are set in resources.groovy. Unit test fails on @PostConstruct asserts. Tried setting up the dependencies manually in setUpSpec to no avail. Even without a @TestFor, ServiceUnitTestMixin kicks in and merrily chokes on @PostConstruct. Opened a defect GRAILS-11878 which was closed promptly with an advice to use @FreshRuntime and doWithSpring. 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. 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.

I tried implementing org.springframework.beans.factory.InitializingBean just now and that worked, so you might get further with that.@Transactional will also be ignored - the "database" is a ConcurrentHashMap, so you wouldn't get far with that anyway.

If you need real Spring behavior, use integration tests. Unit tests are fast and convenient but only useful for a fairly limited number of scenarios.

这篇关于Grails单元测试在@PostConstruct上失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆