Groovy / Spock:指定将哪些值传递给mock的闭包

时间:2013-11-30 20:36:58

标签: unit-testing groovy mocking spock

首先,这是我第一天用spock,所以请耐心等待我; - )。

如何为下一个受测试的课程设定期望?

class JobThing {
    Logger log;

    void loppy(Sql sql) {
        sql.eachRow("select x from y") {
            z -> log.info("${z.x}")
        }
    }
}

我想假装select语句返回“a”然后返回“b”。 这就是我想出来的

def "loppy"() {
    setup:
    def job = new JobThing()
    job.log = Mock(Logger)
    Sql sql = Mock(Sql)

    when:
    job.loppy(sql)

    then:
    //if sql.eachRow(...) is called then call its closure with value "a" then value "b"
    1 * sql.eachRow('select x from y') {
        // declare expected values here? or where?
    }
    1 * job.log.info("a")
    1 * job.log.info("b")
}

这只是我提出的许多变种中的一种......直到现在才有效。文档没有多大帮助,因为我似乎找不到好的关键词来搜索。

由于

1 个答案:

答案 0 :(得分:0)

首先,你需要考虑你要测试什么。 “Loppy”似乎不够明确。 我不太确定,只是粗略地说,将你的测试分成两个这样的特征方法:

class JobThingSpec extends Specification {

    def sql = Mock(Sql)
    def log = Mock(Logger)
    def job = new JobThing(log: log)

    def 'proper query is executed'() {
        when:
        job.loppy(sql)

        then:
        1 * sql.eachRow('select x from y', _)

    }

    def 'query result is logged'() {
        given:
        sql.rows(_) >> [[x:'a'], [x:'b']]

        when:
        job.loppy(sql)

        then:
        1 * log.info('a')
        1 * log.info('b')
    }
}

通过这种方式,您可以将您的案例很好地分解为单独的测试步骤 - 这本身就更好(可读性,测试失败反馈)。

此外,你不必担心传递的Closure,因为它不容易测试,在你的情况下毫无意义。但是,如果你仍然需要让我知道,我们可以找到一种方法。

更新:

只需调整您的方法:

void loppy(Sql sql) {
    List<Map> result = sql.rows("select x from y")
    result.each { z ->
        log.info("${z.x}")
    }
}