我不确定我是在滥用基于交互的测试还是在做概念上错误的事情。我正在开发一个Spring Boot应用程序(Kotlin),测试使用的是Spock / Groovy。
我有一个正在测试的类,该类调用另一个服务来查询信息。被测类应该缓存结果。但是,我无法模拟具有返回值的方法并检查调用次数,因为一旦添加检查调用,模拟方法始终会返回null。
我创建了一个孤立的示例来演示该问题。
这是要测试的课程:
@Service
class DemoService(private val downstreamService: DownstreamService) {
fun demo(id: String): String {
val something = downstreamService.something(id)
return something
}
}
正在使用此服务的
@Service
class DownstreamService {
fun something(id: String): String {
return id
}
}
这就是我的测试结果:
class DemoServiceTest extends Specification {
def downStream = Mock(DownstreamService)
def demoService = new DemoService(downStream)
def "value check"() {
given:
def test = "my test string"
downStream.something(test) >> "xxx"
when:
def actual = demoService.demo(test)
then:
actual == "xxx" // works
}
def "invocation check"() {
given:
def test = "my test string"
downStream.something(test) >> "xxx"
when:
demoService.demo(test)
then:
1 * downStream.something(test) // works
}
def "combined check"() {
given:
def test = "my test string"
downStream.something(test) >> "xxx"
when:
def demo = demoService.demo(test)
then:
1 * downStream.something(test)
demo == "xxx" // fails because demo is null
}
}
前两个测试按预期工作,但最后一个失败,因为在添加调用检查时返回值始终为null。
答案 0 :(得分:1)
将模拟与调用计数检查结合起来会出现问题,因为那时不调用模拟。
您可以通过这种方式重写组合测试以使其正常工作:
def "combined check"() {
given:
def test = 'my test string'
when:
def demo = demoService.demo(test)
then:
1 * downStream.something(test) >> 'xxx'
demo == 'xxx'
}
答案 1 :(得分:0)
Spock 将根据 * 或 >>、> 运算符解释交互。 并且 then 块中的交互将优先于 given 或 when: 块中的交互。
由于 then 块中的交互未指定响应,因此默认响应将为空。
如 answer
中所述,交互和存根应该一起进行详细解释可以参考文档:)