升级到 Grails 3.0.6 后使用动态查找器时使用 HibernateTestMixin 进行单元测试中的 MissingMethodException
MissingMethodException in unit test with HibernateTestMixin when using dynamic finder after upgrade to Grails 3.0.6
将 Grails 2.5.1 应用程序升级到 Grails 3.0.6 后,我无法让我的单元测试再次运行。
我有一个非常简单的域 class,名为 Team
。
class Team {
String name
String shortName
String image = 'noimage.jpg'
static constraints = {
name nullable: false, maxSize: 30, unique: true
shortName nullable: true, maxSize: 5
image nullable: false, maxSize: 30
}
}
和执行此操作的单元测试
@TestMixin(HibernateTestMixin)
@Domain([Team])
class TeamSpec extends Specification {
def setup() {
new Team(name: 'Hello', shortName: 'Big').save()
}
def cleanup() {
}
void "test something"() {
expect:"fix me"
!Team.findByName('hello')
}
}
当我执行单元测试时,出现以下运行时错误
groovy.lang.MissingMethodException: No signature of method: static abc.Team.findByName() is applicable for argument types: (java.lang.String) values: [hello]
at abc.TeamSpec.test something(TeamSpec.groovy:24)
它抱怨 Grails 2 中可用的动态查找器。5.x。谁能帮我解决这个问题?有人有过这样的经历吗?
编辑
我创建了一个普通的新 Grails 3.0.6 并通过任务 create-domain-class
生成了一个域 class。然后我将三个字符串属性(name、shortName、image)添加到 class 并写了一个简单的断言 !Team.findByName('A')
但异常仍然存在。
编辑 2
我仍然不知道我做错了什么。我向 Grails-Core issue tracker. Example code can be found here
报告了这个问题
编辑 3
@TestFor
可以完成这项工作,但我想使用 HibernateTestMixin
而不是 DomainClassUnitTestMixin
来支持内存数据库中的 H2。因此我添加了
testCompile 'org.grails:grails-datastore-test-support:4.0.5.RELEASE'
给我的 build.gradle
。但是当我添加 HibernateTestMixin
时,出现以下异常。
org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.grails.datastore.mapping.simple.SimpleMapDatastore] is defined
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:371)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:331)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:968)
at grails.test.mixin.domain.DomainClassUnitTestMixin.getSimpleDatastore(DomainClassUnitTestMixin.groovy:76)
at grails.test.mixin.domain.DomainClassUnitTestMixin.mockDomains(DomainClassUnitTestMixin.groovy:86)
at grails.test.mixin.domain.DomainClassUnitTestMixin.mockDomain(DomainClassUnitTestMixin.groovy:119)
at grails.test.mixin.domain.DomainClassUnitTestMixin.mockDomain(DomainClassUnitTestMixin.groovy:118)
at org.spockframework.util.ReflectionUtil.invokeMethod(ReflectionUtil.java:153)
at org.spockframework.runtime.model.MethodInfo.invoke(MethodInfo.java:84)
at org.spockframework.runtime.extension.MethodInvocation.proceed(MethodInvocation.java:88)
at org.spockframework.runtime.extension.builtin.AbstractRuleInterceptor.evaluate(AbstractRuleInterceptor.java:37)
at grails.test.runtime.TestRuntimeJunitAdapter.evaluate(TestRuntimeJunitAdapter.groovy:46)
at org.spockframework.runtime.extension.builtin.TestRuleInterceptor.intercept(TestRuleInterceptor.java:38)
at org.spockframework.runtime.extension.MethodInvocation.proceed(MethodInvocation.java:87)
at org.spockframework.runtime.extension.MethodInvocation.proceed(MethodInvocation.java:88)
at org.spockframework.runtime.extension.builtin.AbstractRuleInterceptor.evaluate(AbstractRuleInterceptor.java:37)
at grails.test.runtime.TestRuntimeJunitAdapter.evaluate(TestRuntimeJunitAdapter.groovy:73)
at org.spockframework.runtime.extension.builtin.ClassRuleInterceptor.intercept(ClassRuleInterceptor.java:38)
at org.spockframework.runtime.extension.MethodInvocation.proceed(MethodInvocation.java:87)
at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecuter.runTestClass(JUnitTestClassExecuter.java:86)
at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecuter.execute(JUnitTestClassExecuter.java:49)
at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassProcessor.processTestClass(JUnitTestClassProcessor.java:64)
at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.processTestClass(SuiteTestClassProcessor.java:50)
at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)
at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
at org.gradle.messaging.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:32)
at org.gradle.messaging.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:93)
at org.gradle.api.internal.tasks.testing.worker.TestWorker.processTestClass(TestWorker.java:106)
at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)
at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
at org.gradle.messaging.remote.internal.hub.MessageHub$Handler.run(MessageHub.java:360)
at org.gradle.internal.concurrent.DefaultExecutorFactory$StoppableExecutorImpl.run(DefaultExecutorFactory.java:64)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
它应该可以正常工作 - 这个例子使用的是 grails 3.0.1。 http://grails.github.io/grails-doc/3.0.1/guide/testing.html#unitTestingDomains
我猜使用@TestFor 批注可能对您有用。它将根据您正在测试的内容设置所需的任何 mixins。这是我的工作示例,位于
/src/test/groovy/grails3test/TeamSpec.groovy:
package grails3test
import grails.test.mixin.TestFor
import spock.lang.Specification
/**
* See the API for {@link grails.test.mixin.domain.DomainClassUnitTestMixin} for usage instructions
*/
@TestFor(Team)
class TeamSpec extends Specification {
def setup() {
Team t = new Team(name: 'alphabravo')
t.save()
}
def cleanup() {
}
void "test something"() {
expect:
Team.findByName('alphabravo') != null
}
}
该行为正式是一个错误,将在 Grails 3.0.8 版本中修复
将 Grails 2.5.1 应用程序升级到 Grails 3.0.6 后,我无法让我的单元测试再次运行。
我有一个非常简单的域 class,名为 Team
。
class Team {
String name
String shortName
String image = 'noimage.jpg'
static constraints = {
name nullable: false, maxSize: 30, unique: true
shortName nullable: true, maxSize: 5
image nullable: false, maxSize: 30
}
}
和执行此操作的单元测试
@TestMixin(HibernateTestMixin)
@Domain([Team])
class TeamSpec extends Specification {
def setup() {
new Team(name: 'Hello', shortName: 'Big').save()
}
def cleanup() {
}
void "test something"() {
expect:"fix me"
!Team.findByName('hello')
}
}
当我执行单元测试时,出现以下运行时错误
groovy.lang.MissingMethodException: No signature of method: static abc.Team.findByName() is applicable for argument types: (java.lang.String) values: [hello]
at abc.TeamSpec.test something(TeamSpec.groovy:24)
它抱怨 Grails 2 中可用的动态查找器。5.x。谁能帮我解决这个问题?有人有过这样的经历吗?
编辑
我创建了一个普通的新 Grails 3.0.6 并通过任务 create-domain-class
生成了一个域 class。然后我将三个字符串属性(name、shortName、image)添加到 class 并写了一个简单的断言 !Team.findByName('A')
但异常仍然存在。
编辑 2 我仍然不知道我做错了什么。我向 Grails-Core issue tracker. Example code can be found here
报告了这个问题编辑 3
@TestFor
可以完成这项工作,但我想使用 HibernateTestMixin
而不是 DomainClassUnitTestMixin
来支持内存数据库中的 H2。因此我添加了
testCompile 'org.grails:grails-datastore-test-support:4.0.5.RELEASE'
给我的 build.gradle
。但是当我添加 HibernateTestMixin
时,出现以下异常。
org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.grails.datastore.mapping.simple.SimpleMapDatastore] is defined
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:371)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:331)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:968)
at grails.test.mixin.domain.DomainClassUnitTestMixin.getSimpleDatastore(DomainClassUnitTestMixin.groovy:76)
at grails.test.mixin.domain.DomainClassUnitTestMixin.mockDomains(DomainClassUnitTestMixin.groovy:86)
at grails.test.mixin.domain.DomainClassUnitTestMixin.mockDomain(DomainClassUnitTestMixin.groovy:119)
at grails.test.mixin.domain.DomainClassUnitTestMixin.mockDomain(DomainClassUnitTestMixin.groovy:118)
at org.spockframework.util.ReflectionUtil.invokeMethod(ReflectionUtil.java:153)
at org.spockframework.runtime.model.MethodInfo.invoke(MethodInfo.java:84)
at org.spockframework.runtime.extension.MethodInvocation.proceed(MethodInvocation.java:88)
at org.spockframework.runtime.extension.builtin.AbstractRuleInterceptor.evaluate(AbstractRuleInterceptor.java:37)
at grails.test.runtime.TestRuntimeJunitAdapter.evaluate(TestRuntimeJunitAdapter.groovy:46)
at org.spockframework.runtime.extension.builtin.TestRuleInterceptor.intercept(TestRuleInterceptor.java:38)
at org.spockframework.runtime.extension.MethodInvocation.proceed(MethodInvocation.java:87)
at org.spockframework.runtime.extension.MethodInvocation.proceed(MethodInvocation.java:88)
at org.spockframework.runtime.extension.builtin.AbstractRuleInterceptor.evaluate(AbstractRuleInterceptor.java:37)
at grails.test.runtime.TestRuntimeJunitAdapter.evaluate(TestRuntimeJunitAdapter.groovy:73)
at org.spockframework.runtime.extension.builtin.ClassRuleInterceptor.intercept(ClassRuleInterceptor.java:38)
at org.spockframework.runtime.extension.MethodInvocation.proceed(MethodInvocation.java:87)
at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecuter.runTestClass(JUnitTestClassExecuter.java:86)
at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecuter.execute(JUnitTestClassExecuter.java:49)
at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassProcessor.processTestClass(JUnitTestClassProcessor.java:64)
at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.processTestClass(SuiteTestClassProcessor.java:50)
at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)
at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
at org.gradle.messaging.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:32)
at org.gradle.messaging.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:93)
at org.gradle.api.internal.tasks.testing.worker.TestWorker.processTestClass(TestWorker.java:106)
at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)
at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
at org.gradle.messaging.remote.internal.hub.MessageHub$Handler.run(MessageHub.java:360)
at org.gradle.internal.concurrent.DefaultExecutorFactory$StoppableExecutorImpl.run(DefaultExecutorFactory.java:64)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
它应该可以正常工作 - 这个例子使用的是 grails 3.0.1。 http://grails.github.io/grails-doc/3.0.1/guide/testing.html#unitTestingDomains
我猜使用@TestFor 批注可能对您有用。它将根据您正在测试的内容设置所需的任何 mixins。这是我的工作示例,位于
/src/test/groovy/grails3test/TeamSpec.groovy:
package grails3test
import grails.test.mixin.TestFor
import spock.lang.Specification
/**
* See the API for {@link grails.test.mixin.domain.DomainClassUnitTestMixin} for usage instructions
*/
@TestFor(Team)
class TeamSpec extends Specification {
def setup() {
Team t = new Team(name: 'alphabravo')
t.save()
}
def cleanup() {
}
void "test something"() {
expect:
Team.findByName('alphabravo') != null
}
}
该行为正式是一个错误,将在 Grails 3.0.8 版本中修复