【发布时间】:2019-10-20 05:32:48
【问题描述】:
对于少数测试用例,我尝试遵循 DRY 原则,其中只有交互在相同的测试用例条件下有所不同。我找不到在interaction { } 块中实现多种方法的方法。
正如http://spockframework.org/spock/docs/1.3/interaction_based_testing.html#_explicit_interaction_blocks 中所述,我在then: 块中使用interaction { },如下所示:
Java 代码:
// legacy code (still running on EJB 1.0 framework, and no dependency injection involved)
// can't alter java code base
public voidGetData() {
DataService ds = new DataService();
ds = ds.findByOffset(5);
Long len = ds.getOffset() // happy path scenario; missing a null check
// other code
}
// other varieties of same code:
public voidGetData2() {
ItemEJB tmpItem = new ItemEJB();
ItemEJB item = tmpItem.findByOffset(5);
if(null != item) {
Long len = item.getOffset();
// other code
}
}
public voidGetData3() {
ItemEJB item = new ItemEJB().findByOffset(5);
if(null != item) {
Long len = item.getOffset();
// other code
}
}
Spock 测试:
def "test scene1"() {
given: "a task"
// other code ommitted
DataService mockObj = Mock(DataService)
when: "take action"
// code omitted
then: "action response"
interaction {
verifyNoDataScenario() // How to add verifyErrorScenario() interaction to the list?
}
}
private verifyDataScenario() {
1 * mockObj.findByOffset(5) >> mockObj // the findByOffset() returns an object, so mapped to same mock instance
1 * mockObj.getOffset() >> 200
}
private verifyErrorScenario() {
1 * mockObj.findByOffset(5) >> null // the findByOffset() returns null
0 * mockObj.getOffset() >> 200 // this won't be executed, and should ie expected to throw NPE
}
interaction 闭包不接受多个方法调用。我不确定这是否是设计限制。我相信在闭包中可以做的不仅仅是提到方法名称。我还尝试将 mockObj 插入为变量并使用数据管道/数据表,但由于它引用了相同的模拟实例,所以它不起作用。我将把它作为一个单独的问题发布。
我最终重复了两次测试用例,只是为了调用不同的交互方法。下线我看到更多的场景,并希望避免复制和粘贴方法。感谢任何实现这一目标的指针。
更新:
- 修改了共享 java 代码,因为早期的 DataService 名称令人困惑。
- 由于不涉及 DI,而且我没有找到模拟方法变量的方法,所以我使用 PowerMockito 模拟它们,例如
PowerMockito.whenNew(DataService.class).withNoArguments().thenReturn(mockObj)
【问题讨论】:
-
你好。你问了一个问题,我回答了。在您提出后续问题后,您没有提供我要求的 MCVE。我会很感激你接受+赞成我的回答,因为它非常详细地回答了你最初的问题。
标签: unit-testing spock powermock powermockito