【问题标题】:Throw IOException in multiple return results with Spock使用 Spock 在多个返回结果中抛出 IOException
【发布时间】:2015-10-27 15:58:22
【问题描述】:

我正在测试错误处理。我希望第一次调用mockedObject.foo() 抛出一个新的 IOException,第二次调用返回 bar。我尝试了以下代码,

mockedObject.foo() >>> [{throw new IOException()}, bar]

但是,当我运行测试时,我收到一个错误,指出不能将闭包强制转换为 Bar,

FooSpec$_$spock_feature_0_1_closure2 不能转换为 Bar

如何使用 Spock 模拟这种行为?

编辑:看到 tim_yates 引用的文档后,我只是将测试更改为,

mockedObject.foo() >>> firstBar >> {throw new IOException()} >> secondBar

这已经足够接近测试我需要测试的内容了。下面的代码抛出了同样的异常,所以我猜 Spock 是根据第一个对象返回来设置模拟方法的返回类型。

mockedObject.foo() >>> {throw new IOException()} >> secondBar

【问题讨论】:

    标签: groovy spock


    【解决方案1】:

    你应该可以做到:

    mockedObject.foo() >>> {throw new IOException()} >> bar
    

    (See here in the documentation)

    【讨论】:

    • 感谢您提供文档链接。不幸的是,我使用该代码得到了相同的结果。
    • 被测方法foo()是什么样子的?
    • 'foo()' 未在测试中。被测方法基本是循环调用foo和处理错误。
    • @Matt_Bro 确保匹配foo() 调用中的参数。如果您不关心参数,最安全的方法是使用 mockedObject.foo(*_) >>> {throw new IOException()} >> bar。在嘲笑时注意*_。如果 foo 有一个参数,那么 mockedObject.foo(_) >>> {throw new IOException()} >> bar 应该可以工作
    • 查看文档,看起来三重右移运算符用于值数组。链接值(异常关闭,然后是条形图)“通常”应该按需要运行。
    【解决方案2】:

    这里是一个完整的工作示例:

    @Grab('org.spockframework:spock-core:0.7-groovy-2.0')
    @Grab('cglib:cglib:3.1') 
    @Grab('org.ow2.asm:asm-all:5.0.3') 
    
    import spock.lang.*
    
    class MyTestSpec extends Specification {    
       def 'spec'() {
          given:
          def a = new A()
          a.b = Mock(B) {
             foob() >> { throw new Exception('aaa') } >> 1
          }
    
          when:
          a.fooa()
    
          then:
          def e = thrown(Exception)        
          e.message == 'aaa'
    
          when:
          def r = a.fooa()
    
          then:
          r == 1
       }
    }
    
    class A {
    
        B b = new B()
    
        Integer fooa() {
            b.foob()
        }
    }
    
    class B {
        Integer foob() {
            2
        }
    }
    

    【讨论】:

      【解决方案3】:

      你可以尝试拆分'then'块:

      然后: 1 * mockedObject.foo() >> {throw new IOException()}

      ....(其他一些调用断言)

      然后: 1 * mockedObject.foo() >> bar.

      我知道这个话题很老了,但也许有人仍然想找到它的解决方案。 (Spock测试:根据Invocation Order抛出异常或值) 请参考:https://spockframework.org/spock/docs/1.0/interaction_based_testing.html 调用顺序部分

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-06-08
        • 1970-01-01
        • 2012-04-18
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多