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

What does @TestFor do in a unit test for a domain?

在 Grails 3 中为某些 class 编写单元测试时,我可以使用 @TestFor 注释来指定我要测试的 class。在我的单元测试中,如果我的 class 被测试是一个控制器,我有一个字段 "controller" 和一个字段 "service" 如果我正在测试服务,我可以使用这些字段作为 "system under test".

我想知道 @TestFor 在域 class 的测试中做了什么以及应该如何使用它。我找不到任何处理这种情况的文件。假设我有一个域 "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: Cannot cast object 'class MyDomain' with class 'java.lang.Class' to class 'MyDomain'

这可能意味着 Grails 试图使用表示 MyDomain class 的对象作为此 class 的实例。我想知道为什么会这样,代码有什么问题?我的意思是,domain属性 存在,它存在是有原因的,还是不是?如何使用仅在访问时抛出异常的 属性?

更新
显然只有当域 class 中有一个字段 String name 时才会抛出异常。我不知道这个领域有什么特别之处。这可能只是一个错误吗?

@TestFor 注释为 Grails 域 class 做了很多事情,但最重要的是它模拟了域的行为和 GORM 功能,并提供了 getter returns 域的实例 class.

域 classes 被注册为原型 Spring beans,所以 getter 只是向应用程序上下文请求一个新实例,然后将该实例设置为私有 $domain 字段,该字段在对 getter 的后续调用中返回。请注意,您的 def doesntMatter = domain 正在使用此生成的 getter 并且等效于 def doesntMatter = getDomain() 其中 getDomain() returns MyDomain.[=18 的新实例=]

听起来你的假设是正确的。调用 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 中的错误有关,应在下一个版本中修复,请参阅 https://github.com/grails/grails-core/issues/10363