You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

编写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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 06:42:56