unit-testing - Grails 测试失败的域保存在服务中

标签 unit-testing grails spock

我有一个 Grails (3+) 服务,其中从数据库中检索域对象,修改,然后在数据库中更新。

class MyService {
    def modifyObject(String uuid) {
        def md = MyDomain.findByUuid(uuid)
        md.someField = true
        if (!md.save()){ 
            throw new MyException()
        }
    }
}

现在我需要用否定测试来测试这个服务方法 ,以确保抛出异常。但我不知道如何强制失败 save在服务方法中。
@TestFor(MyService)
@Mock(MyDomain)
class MyServiceSpec extends Specification {

    void "test An exceptionl situation was found"() {
        given: "An uuid"
            def md = new MyDomain(uuid: "123")
            md.save(failOnError: true)

        when: "service is called"
            service.modifyObject("123")

        then: "An exception is thrown"
            thrown MyException
    }
}

显然,以更实用的方式重新定义服务方法(对象直接传递给方法,修改并返回而不保存。例如 MyDomain modifyObject(MyDomain md) )将是一个很好的解决方案,因为我可以在外部创建无效的临时对象或甚至在方法执行后使其无效。

但问题是:“ 有没有办法按原样测试服务代码?

最佳答案

假设您确实想抛出异常而不仅仅是处理验证错误,那么可以确定。您将希望利用 Spock 对基于交互的测试的支持并利用静态方法 stub 。见类似问题,Unit test grails with domain objects using GORM functions .

您需要一些方法来隔离服务方法并 stub GORM 功能。这对于静态方法可能很棘手,但可以使用全局 GroovyMock 或 GroovySpy 来完成。 .本质上,您正在替换所有实例/对 MyDomain 的引用。在方法的持续时间内(尽管 GroovySpy 将依赖于实际的域类,除非交互匹配)。

有了 Mock/Spy,您可以指定您期望发生的交互,并指定这些交互应该返回什么。在这种情况下,我们期望 findByUuid使用参数 "123" 调用一次,我们返回一个模拟 MyDomain目的。然后那个模拟对象有它 save()方法在我们返回 null 的地方调用一次,即保存失败。

void "test An exceptional situation was found"() {
    setup:
        GroovySpy(MyDomain, global: true)
        def mockDomain = Mock(MyDomain)

    when: "service is called"
        service.modifyObject("123")

    then: "An exception is thrown"
        1 * MyDomain.findByUuid("123") >> mockDomain
        1 * mockDomain.save() >> null
        thrown Exception
}

关于unit-testing - Grails 测试失败的域保存在服务中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35085787/

相关文章:

grails - Grails插件的配置

gradle - GradleRunner将构建目录放在哪里?

已命名静态构造函数的 PHPUnit 模拟类

unit-testing - 创建测试工具(单元测试)

c++ - 系统编程中的单元测试?

unit-testing - Grails 2.3.5。使用 “test-app”而不是 “test-app functional:”时功能测试中的基本URL更改

groovy - JMockit MockUp 在 Spock 测试之间持续存在

java - Powermock验证静态方法中的私有(private)静态方法调用

grails - 在服务中抛出异常时在哪里加载 grails 消息

grails - 用于 Groovy 和 Grails 开发的 Vagrant box