Unit testing @TestFor在域的单元测试中做什么?

Unit testing @TestFor在域的单元测试中做什么?,unit-testing,grails,grails-domain-class,Unit Testing,Grails,Grails Domain Class,在Grails3中为某个类编写单元测试时,我可以使用@TestFor注释来指定要测试的类。在我的单元测试中,如果我测试的类是控制器,那么我有一个字段“controller”,如果我测试的是服务,那么我有一个字段“service”,我可以使用这些字段作为“测试中的系统” 我想知道@TestFor在域类的测试中做了什么,以及应该如何使用它。我找不到任何关于这个案子的文件。假设我有一个域“MyDomain”和一个测试“MyDomainSpec”,其开头如下: @TestFor(MyDomain) cl

在Grails3中为某个类编写单元测试时,我可以使用
@TestFor
注释来指定要测试的类。在我的单元测试中,如果我测试的类是控制器,那么我有一个字段“controller”,如果我测试的是服务,那么我有一个字段“service”,我可以使用这些字段作为“测试中的系统”

我想知道
@TestFor
在域类的测试中做了什么,以及应该如何使用它。我找不到任何关于这个案子的文件。假设我有一个域“MyDomain”和一个测试“MyDomainSpec”,其开头如下:

@TestFor(MyDomain)
class MyDomainSpec extends Specification {

    def setup() {
        def doesntMatter = domain // just to check access to "domain"
最后一行已经给了我一个答案

org.codehaus.groovy.runtime.typehandling.GroovyCastException:无法将类为“java.lang.class”的对象“class MyDomain”强制转换为类“MyDomain”

这可能意味着Grails试图使用表示MyDomain类的对象作为该类的实例。我想知道为什么会发生这种情况,代码出了什么问题?我的意思是,
属性存在,它存在是有原因的,还是没有?如何使用仅在访问时引发异常的属性

更新

显然,只有在域类中有一个字段
字符串名
时才会引发异常。我不知道这个领域有什么特别之处。这可能只是一个bug吗?

TestFor注释为Grails域类做了很多事情,但最重要的是它模仿域的行为和GORM功能,并提供了一个返回域类实例的getter

域类注册为原型springbean,因此getter只需向应用程序上下文请求一个新实例,然后将该实例设置为私有的
$Domain
字段,该字段在后续调用getter时返回。请注意,您的
def doesntMatter=domain
正在使用此生成的getter,相当于
def doesntMatter=getDomain()
其中
getDomain()
返回
MyDomain
的新实例

听起来你的假设是正确的。调用getter不应导致异常。以下工作很好:

@TestFor(MyDomain)
class MyDomainSpec extends Specification {

    void "a new domain can be saved"() {
        given: "a new instance of MyDomain"
        def d = domain // or getDomain()

        expect:
        d.id == null

        when:
        d.save()

        then:
        d.id != null
    }
}

@Entity
class MyDomain {

}
编辑:
这与Grails中的一个bug有关,应该在下一版本中修复,请参阅。

这似乎是一篇有用的文章。他们在域类@zero01alpha上使用
@TestFor
,这本身就是一个有趣的阅读,谢谢。但是关于TestFor,他们只提到它使“mockForConstraintsTests”方法可用。谢谢!你的代码也适用于我。您确定“每次请求时,getter只是向应用程序上下文请求一个新实例”吗?我的调试器告诉我不是这样的-我连续使用domain或getDomain会得到相同的实例。关于CastException:显然,当MyDomain中有一个字段“String name”时,就会发生这种情况。奇怪…对不起,我错了。如果private
$domain
字段不为空,getter只会从应用程序上下文中请求一个新实例。因此,除非显式设置
$domain=null
,否则将得到相同的实例。好的,我确实看到了
GroovyCastException
字符串名。我将尝试找出原因。这是Grails中的一个bug,应该在下一个版本中修复,请参阅