如何在Grails中设置用于功能测试的测试数据



因此,我们有一个restful服务,希望使用grails中的restclient进行测试。

测试代码应该是这样的。。。

class MyControllerSpec extends Specification {
def setup() {
  this.dbEntity = new DbEntity("someid123").save();
}
void "Test entity GET"{
        given:
            RestBuilder rest = new RestBuilder()
        when: "The DB entity service is hit"
            RestResponse restResponse = rest.post("http://localhost:8080/api/someentity/$id");
        then: "A 200 error is sent"
            restResponse.status == 200

}

我遇到的问题是.save()上的设置方法失败了,因为没有休眠会话。在运行测试之前,如何操作数据库?

您可以定义一个名为"setupData"的方法,并在"测试实体GET"测试用例的"给定"块中调用它。

def setupData() { this.dbEntity = new DbEntity("someid123").save(); }

如果您需要在每次函数测试之前加载一些数据,您可以使用@Shared变量或方法或两者创建一个辅助类。甚至可以覆盖该类中的setup、setupSpec方法。

您的第一个类现在没有扩展Specification,而是扩展DataLoader类(helper类)。

class MyControllerSpec extends DataLoader {
    void setup(){
        createEntity()
    }

    void "Test entity GET"{
            given:
                RestBuilder rest = new RestBuilder()
            when: "The DB entity service is hit"
                RestResponse restResponse = rest.post("http://localhost:8080/api/someentity/$dbEntity.id");
            then: "A 200 error is sent"
                restResponse.status == 200
    }
}

您的helper类是一个扩展Specification的类,它包含方法和@Shared变量。

import spock.lang.Shared
class DataLoader extends Specification {
    @Shared DbEntity dbEntity
    void createEntity(){
        dbEntity = new DbEntity("someid123").save();
    }
}

在Grails 2.5.6中扩展GebSpec时,其他答案都没有帮助:我仍然会得到

类[…]上的方法在Grails应用程序之外使用

在CCD_ 2呼叫上。

@TestFor(DbEntity)添加到测试类有帮助。

注意:虽然这个注释破坏了集成测试,但在这里它似乎是必要的。不确定原因。

您可能想要使用remote-control插件。在Grails 2.x中,将其添加到BuildConfig.groovy:中

repositories {
    ...
    mavenRepo "http://dl.bintray.com/alkemist/maven/"
}
plugins {
    ...
    test ":remote-control:2.0"
}

在刷新依赖项并可能调整一些设置(例如,请参阅此处和此处)之后,您可以在测试中这样使用它:

// <project>/test/functional/<package>/MyControllerSpec.groovy
class MyControllerSpec extends GebSpec {
    RemoteControl remote        
    DbEntity dbEntity
    def setup() {
        this.remote = new RemoteControl()           
        this.dbEntity = remote {
            new DbEntity("someid123").save()
        }
    }
    def cleanup() {
        remote {
            DbEntity.findAll().each { dbe ->
                println("Deleting $dbe")
                dbe.delete()
            }
        }
    }

注:

  • 您也可以在given/setupwhen块中调用remote
  • 有时,似乎有必要将核心包裹在remote { ... }中的DbEntity.withTransaction { ... }中。也许这对更受欢迎的人来说是显而易见的;我被那件事绊倒了
  • 如果要从remote返回DbEntity,则它必须是可序列化的

最新更新