Grails插件服务集成测试与GORM是否应该工作



更新

@拉姆沙兰下面的答案是正确的。这可以说是Grails本身的一个缺陷,但肯定是一个文档问题。我在Grails Jira中添加了一个缺陷报告https://jira.grails.org/browse/GRAILS-11595.我还在GitHub中添加了测试代码(包括修复程序(:https://github.com/xnickmx/grails-2.4.2-plugin-integration-test-example


原始问题:

注意:如果我创建一个应用程序而不是一个插件,那么这一系列的步骤就可以了。

概述

我的Grails插件项目有一个服务方法,它试图创建一个域类。从集成测试中调用服务的方法会导致

java.lang.IollegalStateException:类[Domain-class]上的方法在Grails应用程序之外使用。

背景

  1. 在Windows7上运行的Grails 2.4.2版本
  2. 插件项目开始(例如:GrailsTestPlugin(
  3. 创建一个简单的域类(例如:Person(
  4. 使用创建域类实例的方法创建一个简单的服务类(示例:PersonService((示例:createPerson(
  5. 创建一个调用服务类方法的集成测试(例如:PersonServiceITSpec(
  6. 运行测试并获得NullPointerException。症状与GRAILS-10538非常相似(但这个错误提到了单元测试,并被假定为已修复(。它在应用程序和插件项目中都以这种方式失败
  7. 将服务的@Transactional注释更改为static-Transactional=true,然后再次运行测试。这一次测试失败

    java.lang.IllegalStateException:类[org.grails.testplugin.domain.Person]上的方法在grails应用程序之外使用。如果在测试的上下文中正确地使用嘲弄的API或引导Grails运行。网址:org.grails.testplugin.service.PersonService.createPerson(PersonService.groovy:13(

如果我将服务类更改为不再尝试创建域类实例,它就会起作用。

发生了什么事

这看起来像是Grails的基本功能。我很惊讶它似乎在插件项目中不起作用。我做错什么了吗?这不应该起作用吗?是虫子吗?

详细信息

org.grails.testplugin.main.Person.groovy:

package org.grails.testplugin.domain
class Person {
    String name
    static constraints = {
    }
}

org.grails.testplugin.service.PersonService:

package org.grails.testplugin.service
import grails.transaction.Transactional
import org.grails.testplugin.domain.Person
//@Transactional have to comment out to avoid NPE
class PersonService {
    static transactional = true
    Person createPerson(String name) {
    new Person(name: name).save()
    }
}

创建集成测试:

创建集成测试org.rails.testplugin.service.PersonServiceITSpec-

内容:

package org.grails.testplugin.service
import spock.lang.*
import static org.junit.Assert.*
/**
 * Tests PersonService
 */
class PersonServiceITSpec extends Specification {
    private PersonService personService
    def setup() {
        personService = new PersonService()
    }
    def cleanup() {
    }
    void "test createPerson happy path"() {
        given:
        final name = "name"
        when:
        final result = personService.createPerson(name)
        then:
        assertNotNull(result)
        assertEquals(name, result.name)
        assertNotNull(result.getId())
    }
}

运行测试

grails测试应用程序集成:

由于您正在运行集成测试,因此不需要为服务执行new。你的测试应该像这个

import spock.lang.*
class PersonServiceITSpec extends Specification {
    PersonService personService
    def setup() {
    }
    def cleanup() {
    }
    void "test createPerson happy path"() {
        given:
        final String name = 'name'
        when:
        def result = personService.createPerson(name)
        then:
        result != null
        name == result.name
        result.id != null
    }
}

该框架将自动在字段中注入personService,并且它不应该是私有的。

与其扩展Specification类,我更喜欢扩展IntegrationSpec

更新:

错误的原因是缺少hibernate插件当我们创建新插件时,hibernate插件不会添加到插件依赖项中。所以包含域的测试会产生问题。所以添加

runtime ":hibernate4:4.3.5.4" // or ":hibernate:3.6.10.16"

在BuildConfig.groovy中的插件依赖关系。它可能看起来像这个

plugins { build(":release:3.0.1", ":rest-client-builder:1.0.3") { export = false } runtime ":hibernate4:4.3.5.4" // or ":hibernate:3.6.10.16" }

最好将hibernate的范围更改为测试。

最新更新