如何使用模拟使用groovy-spock编写参数化测试

时间:2017-10-24 14:13:46

标签: unit-testing groovy spock

我想使用带有spock的groovy来测试这个类:

class TaskRunner {
    private int threads
    private ExecutorService executorService
    private TaskFactory taskFactory

    // relevant constructor

    void update(Iterable<SomeData> dataToUpdate) {
        Iterable<List<SomeData>> partitions = partition(dataToUpdate, THREADS)
        partitions.each {
            executorService.execute(taskFactory.createTask(it))
        }
    }
}

我想写测试看起来像这样:

class TaskRunnerSpec extends specification {
    ExecutorService executorService = Mock(ExecutorService)
    TaskFactory taskFactory = Mock(TaskFactory)
    @Subject TaskRunner taskRunner = new TaskRunner(taskFactory, executorService)

    def "should run tasks partitioned by ${threads} value"(int threads) {
        given:
        taskRunner.threads = threads

        where:
        threads | _
              1 | _
              3 | _
              5 | _

        when:
        tasksRunner.update(someDataToUpdate())

        then:
        // how to test number of invocations on mocks?
    }
}

我在文档中看到的示例仅包含与givenwhenthen部分进行交互式测试的示例以及数据驱动测试的示例,这些示例仅包含两个部分:expectwhere

我可以把那两个结合起来吗?或者如何实现相同的功能?

2 个答案:

答案 0 :(得分:1)

简短回答是的,可以将它们合并,但不是按顺序排列,请参阅docs where必须是最后一个块。所以given-when-then-where完全没问题。正确测试多线程代码要困难得多,但是因为你嘲笑ExecutorService你不必担心它。

不要忘记@Unroll并注意模板不使用GString语法。

class TaskRunnerSpec extends specification {
    ExecutorService executorService = Mock(ExecutorService)
    TaskFactory taskFactory = Mock(TaskFactory)
    @Subject TaskRunner taskRunner = new TaskRunner(taskFactory, executorService)

    @Unroll
    def "should run tasks partitioned by #threads value"(int threads) {
        given:
        taskRunner.threads = threads

        when:
        tasksRunner.update(someDataToUpdate())

        then:
        threads * taskFactory.createTask(_) >> new Task() // or whatever it creates
        threads * executorService.execute(_)

        where:
        threads | _
              1 | _
              3 | _
              5 | _

    }
}

答案 1 :(得分:0)

BTW,where块可以简化为一行:

where:
threads << [1, 3, 5]