Spock:从方法中捕获 return 值?

Spock: capture return value from a method?

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

我想到的是这样的:

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

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

No signature of method: core.ConsoleHandler.compileOutputLines() is applicable for argument types: (org.spockframework.lang.Wildcard) values: [[*_]]

如果我尝试同样的问题:

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

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

使用间谍对象时,您可以调用 callRealMethod() 将方法调用委托给真实对象。这样您就可以捕获 returned 值并对其应用一些断言。考虑以下示例:

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)(我只是以这些参数为例,我猜你的方法有不同的参数列表)returns 任意两个参数的大小为 1 的列表。

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