gpt4 book ai didi

grails - 使用 Spock 和服务类在 Grails 中进行数据驱动测试

转载 作者:行者123 更新时间:2023-12-02 15:00:39 24 4
gpt4 key购买 nike

我正在尝试使用 Spock 为我的 Grails 服务类编写集成测试。

为了获得一些数据来驱动测试,我有一个这样的查询:"select column1, column2, column3 from table where column1 = ?"
我使用我们编写的自定义服务从该查询中获取结果。基本上,它封装了 Groovy 的 Sql 类并为我处理打开和关闭数据库连接。我可以使用 Grails 的典型依赖注入(inject)将其注入(inject)到我的集成测试中。但是,我似乎无法使用它来检索数据驱动测试的数据。这是我的测试课:

class MyServiceSpec extends Specification {
def myService
def sqlService
@Shared tsQuery
@Shared ts

def setupSpec() {
tsQuery = "select column1, column2, column3 from table where column1 = ?"
ts = sqlService.rows(tsQuery, ['someSuch'])
}

def "test a feature"() {
setup:
def ts = sqlService.rows(tsQuery)
def results = myService.getTimesheets(thing1, thing2, thing3)
expect:
//some appropriate expectations based on the data here
where:
timeSheet << ts
thing1 = timeSheet.column1
thing2 = timeSheet.column2
thing3 = timeSheet.column3
}
}

这会引发我不允许在 setupSpec() block 中调用 sqlService 的错误:
Only @Shared and static fields may be accessed from here
ts = sqlService.rows(tsQuery)
^

问题是,如果我让 sqlService @Shared , Grails 依赖注入(inject)不起作用,它只是创建一个空对象。如果我尝试将其设为静态(如 static def sqlService 中的那样),也会发生同样的事情。
java.lang.NullPointerException: Cannot invoke method rows() on null object

我尝试过的解决方法

setupSpec 中的新 SqlService 实例

我尝试初始化一个新的 SqlService 实例,就像在我的 setupSpec block 中一样:
    def setupSpec() {
tsQuery = "select column1, column2, column3 from table where column1 = 'someSuch'"
def sql = new SqlService()
ts = sql.rows(tsQuery)
}

那只是给出一个错误

|错误 2014-06-13 14:52:10,932 [main] 错误 common.SqlService - sqlQuery 中的错误:方法 groovy.sql.Sql# 的方法重载不明确。
由于以下之间的原型(prototype)重叠,无法解析为 [null] 调用哪个方法:
[接口(interface) javax.sql.DataSource]
[接口(interface)java.sql.Connection]

在 setup 方法中定义 sqlService

如果我不使用 setupSpec(),而是使用 setup(),然后放一个 def sqlService在其中,则 sqlService 对象为空,因此我收到“无法在空对象上调用方法行()”错误。

如果我改为 def sqlService = new SqlService() ,然后我得到与在 setupSpec() 中执行的相同的错误,说 javax.sql.Datasource 和 java.sql.Connection 之间存在重叠的原型(prototype)。

底线

任何人都知道我如何在 Spock 测试中使用另一个服务类作为数据提供者?

最佳答案

所以,这就是我的工作测试类最终的样子:

package edu.missouristate.employee.dts

import spock.lang.*
import static org.junit.Assert.*
import org.junit.*
import groovy.sql.Sql
class MyServiceSpec extends Specification {
def myService
def dataSource
@Shared tsQuery
@Shared ts

def setup() {
tsQuery = '''select column1, column2, column3
from table where column1 = ?
and rownum < 6'''
def sql = new Sql(dataSource)
ts = ts ?: sql.rows(tsQuery, ['someSuch'])
sql.close()
}

def "dummy test"() { //This is just to get the spec initialized.
expect:
1==1
}

def "test a feature"() {
setup:
def results = myService.getTimesheets(timeSheet.thing1, timeSheet.thing2, timeSheet.thing3)
expect:
//some appropriate expectations based on the data here, e.g.
results[0].someProperty == timeSheet.correspondingDatabaseColumn
where:
timeSheet << ts
}
}

简而言之,我放弃了使用自己的 sqlService 类,而直接使用 Groovy Sql 类。

其他注意事项:我在测试方法和迭代中有效地重用了 ts 对象,因为我真的只想从数据库中提取一次数据。我还在我的查询中添加了一个 rownum 限制,所以它只会做这么多的迭代。

由于 setup block 必须引用 dataSource(反过来,需要用 def dataSource 声明),它需要是 setup() 而不是 setupSpec()。然而,由于 Spock 实际上开始评估 where:在 setup() 夹具之前阻塞,我必须添加一个虚拟测试方法来填充 ts 变量。向@Mario David 的 Prop 指出我在那个方向上的正确方向。

关于grails - 使用 Spock 和服务类在 Grails 中进行数据驱动测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24213060/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com