Exception Spock测试Where块中的异常处理
我正在测试一个具有一些依赖关系的服务方法;我想断言,如果这些依赖项中的任何一个抛出异常,服务方法应该返回一个默认值 我想写的服务和测试是这样的Exception Spock测试Where块中的异常处理,exception,groovy,spock,data-driven-tests,Exception,Groovy,Spock,Data Driven Tests,我正在测试一个具有一些依赖关系的服务方法;我想断言,如果这些依赖项中的任何一个抛出异常,服务方法应该返回一个默认值 我想写的服务和测试是这样的 static class Service { def dependency1 def dependency2 def dependency3 def method() { try { def foo = dependency1.get() def bar =
static class Service {
def dependency1
def dependency2
def dependency3
def method() {
try {
def foo = dependency1.get()
def bar = dependency2.get()
def baz = dependency3.get()
return " $foo $bar $baz "
} catch (Exception e) {
println e
return ' default value '
}
}
}
def 'test Service error handling'() {
given:
def dependency1 = Mock(Supplier)
def dependency2 = Mock(Supplier)
def dependency3 = Mock(Supplier)
def serviceUnderTest = new Service(dependency1: dependency1, dependency2: dependency2, dependency3: dependency3)
when:
def result = serviceUnderTest.method()
then:
result == ' default value '
dependency1.get() >> closure1
dependency2.get() >> closure2
dependency3.get() >> closure3
where:
closure1 | closure2 | closure3
{-> throw new Exception('closure1') } | {-> null } | {-> null };
{-> null} | {-> throw new Exception('closure2') } | {-> null };
{-> null} | {-> null} | {-> throw new Exception('closure3') }
}
此测试不起作用,因为它会导致模拟返回文本闭包,而不是这些闭包的结果。当然,这是由于添加了where块造成的,因为任何mock都可以直接返回单个闭包的结果,即dependency1.get>{throw new Exception}
我是被迫将此作为三个独立的测试来编写的,还是有其他方法可以将它们组合起来?如果您编写
dependency1.get>>closure1
您的模拟将返回闭包本身,而不是对其进行计算。评估只发生在GroovyString$foo$bar$baz内部,将评估期间发生的错误消息扩展到其中,但不会升级该异常
你想用
dependency1.get>{closure1}
为了修复你的测试。对闭包进行求值,但同时周围的闭包{}确保仅在调用存根方法时才进行求值,而不是在定义存根方法时才进行求值
一些改进意见:
展开测试,将其拆分为多个具有参数化名称的方法,怎么样?这还有一个很好的副作用,可以帮助IDE和Groovy编译器解析不带分号和{->…语法的where:block。
将模拟方法存根在给定的:块中,而不是不属于它们的then:块中,怎么样?
在模拟定义中存根方法,使测试更紧凑,怎么样?
按照Spock手册的建议,在这个简单的例子中,将when:…then:替换为expect:,怎么样?
包装de.scrum_master.stackoverflow.q57172322
导入spock.lang.Specification
导入spock.lang.Unroll
类ServiceDependenciesThrowingErrorsTest扩展了规范{
@展开
def“服务serviceName中的句柄错误”{
鉴于:
def serviceUnderTest=新服务
dependency1:MockSupplier{get>>{closure1},
dependency2:MockSupplier{get>>{closure2},
dependency3:MockSupplier{get>>{closure3}
期望:
serviceUnderTest.method==“默认值”
哪里:
服务名称| closure1 | closure2 | closure3
A |{抛出新异常'closure1'}{null}|{null}
B{null}{throw新异常'closure2'}{null}
C |{null}|{null}{抛出新异常'closure3'}
}
静态类服务{
def依赖性1
def依赖性2
def依赖性3
def方法{
试一试{
def foo=dependency1.get
def bar=dependency2.get
def baz=dependency3.get
返回$foo$bar$baz
}捕获异常e{
普林顿
返回“默认值”
}
}
}
静态类供应商{
def get{
好啊
}
}
}
这就是我的IDE IntelliJ IDEA中展开时测试执行的样子: