【问题标题】:Spock: capture return value from a method?Spock:从方法中捕获返回值?
【发布时间】:2018-08-06 09:33:11
【问题描述】:

我有一个功能测试,我使用 Spy 进行 CUT:我想知道在事情中间调用的方法是否返回预期结果。

我想到的事情是这样的:

then:
1 * ch.compileOutputLines(_).size() == 5

但这不起作用:Spock然后抱怨

没有方法签名:core.ConsoleHandler.compileOutputLines() 是 适用于参数类型:(org.spockframework.lang.Wildcard) 值:[[*_]]

如果我尝试同样的问题:

then:
def result = 1 * ch.compileOutputLines(_)

但这并不让我感到惊讶。如果这样的机制可用,我认为您必须以某种方式在given 块中配置间谍。

【问题讨论】:

    标签: spock spy


    【解决方案1】:

    使用间谍对象时,您可以调用callRealMethod(),它将方法调用委托给真实对象。通过这种方式,您可以捕获返回的值并对其应用一些断言。考虑以下示例:

    import spock.lang.Specification
    
    class SpyMethodArgsExampleSpec extends Specification {
    
        def "should check a value returned in spied object"() {
            given:
            ConsoleHandler ch = Spy(ConsoleHandler)
    
            when:
            ch.run()
    
            then:
            1 * ch.compileOutputLines(_, _) >> { args ->
                assert callRealMethod().size() == 1
            }
        }
    
        static class ConsoleHandler {
            void run() {
                compileOutputLines(4,5)
            }
            List<String> compileOutputLines(Integer n, Integer m) {
                return [] << n
            }
        }
    }
    

    在这种情况下,我们正在调用ConsoleHandler.run(),我们想检查方法compileOutputLines(Integer n, Integer m)(我只是以这些参数为例,我猜你的方法有不同的参数列表)返回任何两个大小为1的列表参数。

    当然,这是您在技术上可以做到的方式。但是,由于过度指定测试场景,这种测试可能会很快变成瓶颈。示例 ConsoleHandler.run() 方法可能不是解释这一点的最佳选择,但基本上如果您的方法需要一些参数并返回一些结果,您应该关注确定性执行流程(对于 那些 我总是得到 this 结果)而不是 ConsoleHandler.run() 调用什么样的方法以及这些方法在我们正在测试的方法中返回什么。想象一下,您必须重构您测试的方法,并且您决定简化它的主体并可能摆脱 ch.compileOutputLines() 调用。您的方法仍然会为同一组参数返回相同的结果,但是您的测试开始失败,因为它过于关注内部部件。相反,只有当您的方法开始出现错误行为时(例如,它开始为保持不变的参数集返回错误结果),它才会向您发出警报。希望对你有帮助。

    【讨论】:

    • 这是一个很好的答案,主要不是(但也)因为我以前也使用过间谍和callRealMethod() 的好技巧,但尽量远离。首先,我喜欢并支持最后一段中的陈述。
    • 感谢您回答我的问题和最后一段。事实是,我知道我的 TDD 方法通常有些“错误”,不仅是这个问题,而且一般来说:我发现自己经常使用 Spy,但 Spock(和其他)文档说“间谍不是这样好:尝试重新思考事情”。我已经尝试使用 TDD 方法大约一年了,现在永远不会停止......但我真正需要的是与专家携手合作,告诉我我在做什么正确以及什么我不是。不是 TDD 101,我已经做过几次了:但它是如何“在现实世界中”工作的。
    猜你喜欢
    • 2020-07-04
    • 2014-01-23
    • 2016-09-09
    • 1970-01-01
    • 2021-09-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多