当前位置: 动力学知识库 > 问答 > 编程问答 >

unit testing - Groovy/Spock: specify which values are passed into a closure of a mock

问题描述:

first of all, this is my first day with spock, so please be patient with me ;-).

How do I set up expectations for the following class under test?

class JobThing {

Logger log;

void loppy(Sql sql) {

sql.eachRow("select x from y") {

z -> log.info("${z.x}")

}

}

}

I would like to pretend that the select statement returns "a" then "b".

This is what I've come up with

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")

}

This is just one of many variants I've come up with... none worked until now. Docs do not help much since I do not seem to find good keywords to search for.

Thanks

网友答案:

First of all you need to think what are you about to test. "Loppy" doesn't seem to be explicit enough. I'm not sure so just roughly speaking, split your test into two feature methods like this:

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')
    }
}

This way you have your case nicely decomposed into separate test steps - which is better by itself (readability, test fail feedback).

Moreover you don't have to worry about the passed Closure as it is not easy to test and in your case quite pointless. But if you still need that let me know and we can find out a way.

UPDATE:

Just adjust your method like this:

void loppy(Sql sql) {
    List<Map> result = sql.rows("select x from y")
    result.each { z ->
        log.info("${z.x}")
    }
}
分享给朋友:
您可能感兴趣的文章:
随机阅读: