【问题标题】:How to write parametrized tests with groovy-spock using mocks如何使用 groovy-spock 使用 mock 编写参数化测试
【发布时间】:2017-10-24 14:13:45
【问题描述】:

我想用 groovy 和 spock 来测试这个类:

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

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

【问题讨论】:

    标签: unit-testing groovy spock


    【解决方案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 | _
    
        }
    }
    

    【讨论】:

      【解决方案2】:

      顺便说一句,where 块可以简化为一行:

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

      【讨论】:

      • 可以,但这是一种风格选择,取决于个人(团队)的偏好。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-12-29
      • 1970-01-01
      • 2014-05-15
      • 2013-11-27
      • 1970-01-01
      • 2018-12-18
      • 1970-01-01
      相关资源
      最近更新 更多