【问题标题】:Grails unit test of domain class (gorm)领域类(gorm)的Grails单元测试
【发布时间】:2011-09-14 04:16:25
【问题描述】:

开始使用 grails,我想评估 GORM,所以我使用 Spring Tool Suite 创建了一个域类:ClientnamevatNumberregNumber,并且自动创建了测试类。

我添加的单元测试代码是:

package pilot1

import grails.test.*

class ClientTests extends GrailsUnitTestCase {
    protected void setUp() {
        super.setUp()
    }

    protected void tearDown() {
        super.tearDown()
    }

    void testSomething() {
        def instances = []
        def myTestDomain = mockDomain(Client, instances)
        def client = new Client(name:"Test",vatNumber:"323",regNumber:"343")
        client.id =1;
        assertEquals client.name, "Test"
        client.save();
        def res = Client.findByName("Test")
        println instances
        println res
        //assertEquals 1, instances.size()
    }
}

结果是 [] 和 null!我做错了什么?

另外,我还想看看 GORM (Hibernate) 在幕后生成的 SQL。知道如何在 Grails 中做到这一点吗?

【问题讨论】:

  • 如果你用这个作为单元测试,Hibernate 并没有实际使用,也没有 SQL 的使用。这一切都被嘲笑了,一些更微妙的查询(其中大部分,在我有限的经验中)往往找不到东西。集成测试做真正的 Hibernate 工作。
  • 我读过一些关于这个的东西,但我不确定!嗯,这很奇怪来自 java...

标签: hibernate unit-testing grails grails-orm grails-domain-class


【解决方案1】:

不要这样做:client.id =1;

save() 将提供一个 id。

你可能需要保存(flush:true)。

只需保存并使用,然后使用 id 进行获取。

然后进行测试。

此链接可能有用:http://blog.springsource.com/2011/06/07/countdown-to-grails-1-4-unit-testing/

【讨论】:

    【解决方案2】:

    http://www.ibm.com/developerworks/java/library/j-grails10148/index.html

    “正如我之前提到的,Grails 支持两种基本类型的测试:单元测试和集成测试。两者在语法上没有区别——两者都使用相同的断言编写为 GroovyTestCase。区别在于语义。单元测试是意味着单独测试该类,而集成测试允许您在完整的运行环境中测试该类。 坦率地说,如果你想把你所有的 Grails 测试写成集成测试,那对我来说很好。所有 Grails create-* 命令都会生成相应的集成测试,因此大多数人只是使用已有的测试。稍后您将看到,您想要测试的大部分内容都需要完整的环境才能启动并运行,因此集成测试是一个很好的默认设置。”

    【讨论】:

    • 没错。只是“您想要测试的大多数东西都需要完整的环境才能启动并运行”是一个非常糟糕的建议。
    • mockDomain(Client, instances) 允许在没有启动和运行完整环境的情况下测试许多 Gorm 功能。在 grails.org/doc/latest/guide/… 中搜索 mockDomain 部分和示例以获取详细信息。
    • 集成测试与单元测试在批量运行时并不重要,但在运行单个测试或测试用例时,例如在开发它时,单元测试比集成测试快得多。
    • 批量运行是什么意思?
    【解决方案3】:

    首先,您不应该评估 GORM 本身。提供 Grails 的人负责测试 GORM。诚然,你可能不是那个意思。

    其次,测试 findBy*() 通常不是单元测试的关注点。如果确实需要测试 findBy*(),则需要收集所有 findBy*() 响应实例并将该列表作为第二个参数传递给 mockDomain()。您在示例中错误地使用了 mockDomain() - 您必须告诉 mockDomain() 要模拟哪些实例才能在 findBy*() 调用中接收它们。

    【讨论】:

    • mockDomain(Client, instances) 确保在单元测试中连接了 findByName 方法。所以 Client.findByName("Test") 应该返回保存的客户端实例。
    • @Ruben 如果我将 Cris 测试的前两行移到保存后,并修改这两行中的第一行以包含保存的实例,findBy 将起作用。 Cris 没有将实例传递给他的 mockDomain()——这就是我想要表达的。
    • @Jim 但是如果成功将客户端实例添加到模拟域中,则会在使用动态查找器之前调用 client.save()。
    • @Ruben 我无法让 Cris 的示例工作,即使保存成功。您是否还希望“实例”在测试结束时包含“客户”?
    • @Jim 我不希望实例列表在保存后包含客户端实例。而一个快速的小测试也表明情况并非如此。
    【解决方案4】:

    保存客户端可能会失败而不会引发异常,这可以解释为什么 res 为空。试试下面的代码,看看保存客户端是否失败以及为什么失败。

    client.save()
    if(client.hasErrors()){
    // Saving failed, look in client.errors to see the specific reason
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多