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

Mockito如何验证OptionalDouble参数的近似匹配?

解决OptionalDouble的近似匹配问题

没错,你确实需要自定义一个ArgumentMatcher来处理OptionalDouble的近似匹配——Mockito默认没有提供这个场景的现成匹配器,不过实现起来很简单,我给你写个完整示例:

1. 自定义OptionalDouble近似匹配器

首先创建一个实现ArgumentMatcher<OptionalDouble>的类,核心逻辑是判断实际传入的OptionalDouble是否存在值,并且其值和期望值的差值在容忍范围内:

import org.mockito.ArgumentMatcher;
import java.util.OptionalDouble;

public class OptionalDoubleCloseTo implements ArgumentMatcher<OptionalDouble> {
    private final double expectedValue;
    private final double tolerance;

    // 构造方法传入期望值和容忍度
    public OptionalDoubleCloseTo(double expectedValue, double tolerance) {
        this.expectedValue = expectedValue;
        this.tolerance = tolerance;
    }

    @Override
    public boolean matches(OptionalDouble actual) {
        // 如果实际值是 empty,直接不匹配
        if (!actual.isPresent()) {
            return false;
        }
        // 计算差值的绝对值,判断是否在容忍范围内
        double difference = Math.abs(actual.getAsDouble() - expectedValue);
        return difference <= tolerance;
    }

    @Override
    public String toString() {
        // 重写toString,方便匹配失败时Mockito输出清晰的错误信息
        return String.format("OptionalDouble close to %.10f (tolerance: %.10f)", expectedValue, tolerance);
    }
}

2. 在验证中使用自定义匹配器

在你的测试代码里,通过argThat()方法传入这个自定义匹配器即可,用法和你之前的doubleThat()类似:

import static org.mockito.Mockito.argThat;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.times;

// ...

verify(observer, times(1)).accept(
    argThat(new OptionalDoubleCloseTo(x * (1 - y) / z, 0.00000001))
);

3. 可选优化:封装静态工具方法

如果想让调用更简洁,避免每次都new对象,可以封装一个静态工具类:

public class MockitoCustomMatchers {
    public static OptionalDoubleCloseTo optionalDoubleCloseTo(double expected, double tolerance) {
        return new OptionalDoubleCloseTo(expected, tolerance);
    }
}

然后在测试类中静态导入这个方法,调用起来就和Mockito原生匹配器一样顺手了:

import static your.package.MockitoCustomMatchers.optionalDoubleCloseTo;
import static org.mockito.Mockito.argThat;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.times;

// ...

verify(observer, times(1)).accept(
    argThat(optionalDoubleCloseTo(x * (1 - y) / z, 0.00000001))
);

额外注意点

  • 如果你的场景需要匹配空的OptionalDouble,可以在matches()方法里添加逻辑(比如判断!actual.isPresent()时返回true,根据你的需求调整)。
  • 重写toString()非常重要,当验证失败时,Mockito会输出这个方法的返回值,帮你快速对比期望值和实际值的差异。

内容的提问来源于stack exchange,提问作者Tim B

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 06:46:19