因此,我们有一个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
/setup
和when
块中调用remote
- 有时,似乎有必要将核心包裹在
remote { ... }
中的DbEntity.withTransaction { ... }
中。也许这对更受欢迎的人来说是显而易见的;我被那件事绊倒了 - 如果要从
remote
返回DbEntity
,则它必须是可序列化的