如何使用 groovy-spock 使用模拟编写参数化测试
How to write parametrized tests with groovy-spock using mocks
我想使用 groovy 和 spock 来测试这个 class:
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?
}
}
我看到文档中的示例仅包含 given
、when
、then
部分的交互测试以及数据驱动测试的示例,它们只有两个部分:expect
和 where
.
我可以把这两个结合起来吗?或者如何实现相同的功能?
简短回答是的,它们可以组合,但不能按此顺序查看 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 | _
}
}
顺便说一句,where
块可以简化为一行:
where:
threads << [1, 3, 5]
我想使用 groovy 和 spock 来测试这个 class:
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?
}
}
我看到文档中的示例仅包含 given
、when
、then
部分的交互测试以及数据驱动测试的示例,它们只有两个部分:expect
和 where
.
我可以把这两个结合起来吗?或者如何实现相同的功能?
简短回答是的,它们可以组合,但不能按此顺序查看 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 | _
}
}
顺便说一句,where
块可以简化为一行:
where:
threads << [1, 3, 5]