在服务中有@PostConstruct
以确保已设置依赖项。依赖关系在resources.groovy
中设置。 @PostConstruct
断言单元测试失败。试图在setUpSpec
中手动设置依赖项无济于事。即使没有@TestFor
,ServiceUnitTestMixin
也会在@PostConstruct
开始并快速地窒息。
打开了一个缺陷GRAILS-11878,该缺陷已及时关闭,建议使用@FreshRuntime
和doWithSpring
。如果他们真的费心去尝试,他们会遇到以下错误:
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'
受测试服务:
@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.')
}
}
测试:
@FreshRuntime
@TestFor(MovieRipIndexService)
class MovieRipIndexServiceSpec extends Specification {
def doWithSpring = {
serviceHelper(ServiceHelper)
service.genres = serviceHelper.genres
service.includes = serviceHelper.includes
}
}
答案 0 :(得分:1)
单元测试中的Spring支持相当小,并且活动的ApplicationContext
并不真正经历在正在运行的应用程序中的任何生命周期阶段,甚至在集成测试的初始化期间。在使用@TestFor
和/或@Mock
时,您会在课堂中混合使用很多功能,但它几乎完全被伪造出来,因此您可以专注于对测试中的类进行单元测试。
我刚刚尝试实施org.springframework.beans.factory.InitializingBean
这样做有用,所以你可能会更进一步。@Transactional
也会被忽略 - “数据库”是ConcurrentHashMap
,所以你不会无论如何都要远远不够。
如果您需要真正的Spring行为,请使用集成测试。单元测试快速而方便,但仅适用于相当有限的场景。