是否可以动态生成 Spock 测试方法?
Is it possible to dynamically generate Spock test methods?
我有很多重复的测试,我想以某种方式抽象它们。辅助方法一直很有用,但在一定程度上是有用的。如果我能以某种方式在我的 Specification
中以编程方式生成测试方法,我将能够删除大量复制粘贴代码。
具体来说,我正在测试RPC层的方法。如果不以某种方式调用大多数方法,它们肯定会失败。所以我有像这样的 Spock 测试方法:
def observer = Mock(StreamObserver)
def rpc = new UserServiceRpc()
def "draftToOutbox: should fail when called without parent"() {
def request = draftToOutboxRequest().toBuilder().clearParent().build()
when:
rpc.draftToOutbox(request, observer)
then:
1 * observer.onError(_)
1 * observer.onCompleted()
}
def "outboxToDraft: should fail when called without parent"() {
def request = outboxToDraftRequest().toBuilder().clearParent().build()
when:
rpc.outboxToDraft(request, observer)
then:
1 * observer.onError(_)
1 * observer.onCompleted()
}
不幸的是,我不熟悉 Groovy 的元编程(编译时 AST 转换)功能,我不确定如何做到这一点,是否可能,以及这是否是个好主意.一方面我有一些复制粘贴,但另一方面我的测试非常可读。不过,我倾向于两全其美:没有复制粘贴的可读性。
在这种情况下,您可以将 Data Driven Testing 与一些 groovy 内容一起使用,如下所示:
@Unroll
def "#method: should fail when called without parent"() {
given:
def request = "$methodToGetRequest"().toBuilder().clearParent().build()
when:
rpc."$methodToTest"(request, observer)
then:
1 * observer.onError(_)
1 * observer.onCompleted()
where:
methodToTest | methodToGetRequest
'draftToOutbox' | 'draftToOutboxRequest'
'outboxToDraft' | 'outboxToDraftRequest'
}
编辑
一个使用方法指针的例子:
@Shared
String subjectToTest
def setupSpec() {
subjectToTest = "sTring To Test"
}
def "test using method pointers"() {
when:
def result = methodPointer()
then:
result == expectecResult
where:
expectecResult | methodPointer
'STRING TO TEST' | subjectToTest.&toUpperCase
'string to test' | subjectToTest.&toLowerCase
}
我有很多重复的测试,我想以某种方式抽象它们。辅助方法一直很有用,但在一定程度上是有用的。如果我能以某种方式在我的 Specification
中以编程方式生成测试方法,我将能够删除大量复制粘贴代码。
具体来说,我正在测试RPC层的方法。如果不以某种方式调用大多数方法,它们肯定会失败。所以我有像这样的 Spock 测试方法:
def observer = Mock(StreamObserver)
def rpc = new UserServiceRpc()
def "draftToOutbox: should fail when called without parent"() {
def request = draftToOutboxRequest().toBuilder().clearParent().build()
when:
rpc.draftToOutbox(request, observer)
then:
1 * observer.onError(_)
1 * observer.onCompleted()
}
def "outboxToDraft: should fail when called without parent"() {
def request = outboxToDraftRequest().toBuilder().clearParent().build()
when:
rpc.outboxToDraft(request, observer)
then:
1 * observer.onError(_)
1 * observer.onCompleted()
}
不幸的是,我不熟悉 Groovy 的元编程(编译时 AST 转换)功能,我不确定如何做到这一点,是否可能,以及这是否是个好主意.一方面我有一些复制粘贴,但另一方面我的测试非常可读。不过,我倾向于两全其美:没有复制粘贴的可读性。
在这种情况下,您可以将 Data Driven Testing 与一些 groovy 内容一起使用,如下所示:
@Unroll
def "#method: should fail when called without parent"() {
given:
def request = "$methodToGetRequest"().toBuilder().clearParent().build()
when:
rpc."$methodToTest"(request, observer)
then:
1 * observer.onError(_)
1 * observer.onCompleted()
where:
methodToTest | methodToGetRequest
'draftToOutbox' | 'draftToOutboxRequest'
'outboxToDraft' | 'outboxToDraftRequest'
}
编辑
一个使用方法指针的例子:
@Shared
String subjectToTest
def setupSpec() {
subjectToTest = "sTring To Test"
}
def "test using method pointers"() {
when:
def result = methodPointer()
then:
result == expectecResult
where:
expectecResult | methodPointer
'STRING TO TEST' | subjectToTest.&toUpperCase
'string to test' | subjectToTest.&toLowerCase
}