编写Spock单元测试Mock对象时加法测试结果不符,如何解决?
帮你排查两数加法单元测试的问题
我仔细看了你的代码,发现几个关键问题导致测试结果不符合预期,咱们一步步拆解修复:
1. Service的业务逻辑完全偏离需求
你说要做两数加法,但Service.add方法里压根没用到传入的b参数!现在的逻辑是拿a加上HelperAdd.add(a)的结果(也就是a + (a+4)),这和“两数相加”的需求完全不沾边。
另外HelperAdd的add方法现在是接收一个数返回+4的结果,如果它的职责是辅助两数相加,那这个方法的参数都写错了,应该是接收两个int返回它们的和才对。
2. Spock测试的结构和断言完全无效
你的测试写得有点混乱:
- Spock的规范结构是
given-when-then或者given-when-expect,你把when放在given前面,还混了then和expect,顺序错了。 - 你调用了
src.add(request)但没捕获返回值,后面的expect:"4"根本没意义,相当于没做任何断言,自然没法验证结果对不对。 - 虽然Mock的交互设置(
1 * hd.add(_) >> 2)是对的,但因为没断言返回值,你根本不知道实际结果是什么。
3. 修复后的完整代码示例
先修正业务逻辑(假设需求是计算a+b)
首先调整HelperAdd,让它实现两数相加:
class HelperAdd { def add(int a, int b) { return a + b } }
然后修正Service,调用正确的Helper方法并返回结果:
import org.springframework.web.bind.annotation.PostMapping import org.springframework.web.bind.annotation.RequestBody import org.springframework.beans.factory.annotation.Autowired class Service { @Autowired HelperAdd hd @PostMapping(value="/getdocuments") def add(@RequestBody AddModel request) { int a = request.a int b = request.b // 调用Helper的两数相加方法 int c = hd.add(a, b) return c } }
修正Spock测试
现在写一个符合Spock规范的测试,捕获返回值并做断言:
class ControllerTest extends Specification { Service src HelperAdd hd def setup() { hd = Mock() src = new Service(hd: hd) } def "Add two numbers correctly"() { given: "输入a=2、b=3的请求" AddModel request = new AddModel(a: 2, b: 3) // 用@Canonical的构造器更简洁 when: "调用Service的add方法" def result = src.add(request) then: "HelperAdd的add方法会被调用一次,参数是2和3,返回5" 1 * hd.add(2, 3) >> 5 and: "最终结果应该是5" result == 5 } }
如果你的实际需求不是a+b,而是其他逻辑(比如你原本想让结果是4,那可能是希望hd.add(2)返回2,这样Service里的c=2+2=4),那你只需要调整Mock的返回值和断言:
// 测试里的then块改成 1 * hd.add(2) >> 2 and: result == 4
同时确保Service的逻辑是你需要的。
几个小提醒
- 因为
AddModel加了@Canonical,可以直接用new AddModel(a:2, b:3)创建对象,不用写一堆setter,代码更干净。 - Spock测试一定要严格遵循
given-when-then的结构,可读性高还不容易出错。 - 单元测试的核心是验证方法的输出,所以一定要捕获返回值并写断言,光验证Mock交互是不够的。
内容的提问来源于stack exchange,提问作者java
相关产品推荐
相关产品推荐

