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

如何为Jasmine编写自定义匹配器以校验对象属性值是否在指定范围内

看起来你正在搭建一个Jasmine自定义匹配器来校验对象属性的范围,我来帮你把这个实现补全,还加了一些实用的扩展功能,让匹配器更灵活好用。

完整的toLieWithin自定义匹配器实现
// 在测试用例的beforeEach中注册匹配器
beforeEach(() => {
  jasmine.addMatchers({
    toLieWithin: function(util: jasmine.MatchersUtil, customEqualityTesters: jasmine.CustomEqualityTester[]): jasmine.CustomMatcher {
      return {
        compare: function(actual: Record<string, any>, expected: { min: Record<string, any>, max: Record<string, any>, property?: string }): jasmine.CustomMatcherResult {
          const result: jasmine.CustomMatcherResult = { pass: false };

          // 分两种模式:单个属性校验 / 批量校验所有共同属性
          const targetProperty = expected.property;
          let pass = true;
          let failureMessage = '';

          if (targetProperty) {
            // 单个属性校验逻辑
            const actualValue = actual[targetProperty];
            const minValue = expected.min[targetProperty];
            const maxValue = expected.max[targetProperty];

            // 先检查属性是否存在
            if (actualValue === undefined || minValue === undefined || maxValue === undefined) {
              pass = false;
              failureMessage = `Missing required property "${targetProperty}" in actual, min, or max object`;
            } else {
              // 判断是否在范围内(包含边界)
              pass = actualValue >= minValue && actualValue <= maxValue;
              failureMessage = pass 
                ? '' 
                : `Expected ${actualValue} (from actual.${targetProperty}) to lie between ${minValue} (min.${targetProperty}) and ${maxValue} (max.${targetProperty})`;
            }
          } else {
            // 批量校验所有min和max的共同属性
            const commonProperties = Object.keys(expected.min).filter(key => key in expected.max);
            if (commonProperties.length === 0) {
              pass = false;
              failureMessage = 'No common properties found between min and max objects';
              return { pass, message: failureMessage };
            }

            const failedProps: string[] = [];
            commonProperties.forEach(key => {
              const actualVal = actual[key];
              const minVal = expected.min[key];
              const maxVal = expected.max[key];

              if (actualVal === undefined) {
                failedProps.push(`Actual object missing property "${key}"`);
                pass = false;
              } else if (actualVal < minVal || actualVal > maxVal) {
                failedProps.push(`${actualVal} (actual.${key}) is not between ${minVal} and ${maxVal}`);
                pass = false;
              }
            });

            if (!pass) {
              failureMessage = `The following properties failed range check:\n- ${failedProps.join('\n- ')}`;
            }
          }

          // 处理反向断言(not.toLieWithin)
          result.pass = pass;
          result.message = pass 
            ? `Expected ${JSON.stringify(actual)} not to lie within the range defined by min: ${JSON.stringify(expected.min)} and max: ${JSON.stringify(expected.max)}`
            : failureMessage;

          return result;
        }
      };
    }
  });
});
用法示例

1. 校验单个指定属性

如果你只需要校验对象的某一个属性是否在范围内,可以指定property参数:

const actualUser = { age: 25 };
const ageRangeMin = { age: 20 };
const ageRangeMax = { age: 30 };

// 这个断言会通过
expect(actualUser).toLieWithin({ min: ageRangeMin, max: ageRangeMax, property: 'age' });

// 这个断言会失败,会输出清晰的错误提示
expect(actualUser).toLieWithin({ min: ageRangeMin, max: { age: 24 }, property: 'age' });

2. 批量校验所有共同属性

如果需要一次性校验对象的多个属性是否都在对应范围内,不用指定property,匹配器会自动校验min和max对象的所有共同属性:

const actualProduct = { price: 45, stock: 15 };
const productRangeMin = { price: 40, stock: 10 };
const productRangeMax = { price: 50, stock: 20 };

// 所有属性都符合范围,断言通过
expect(actualProduct).toLieWithin({ min: productRangeMin, max: productRangeMax });

// price属性超出范围,断言失败,会列出所有失败的属性
expect(actualProduct).toLieWithin({ min: productRangeMin, max: { price: 44, stock: 18 } });
关键细节说明
  • 边界控制:当前实现包含范围边界(用>=和<=),如果你需要排除边界,直接把判断条件改成actualValue > minValue && actualValue < maxValue即可。
  • 错误提示:匹配器会生成针对性的错误信息,不管是属性缺失还是值超出范围,都能快速定位问题。
  • 反向断言支持:完美兼容not.toLieWithin,会自动生成反向的提示文本。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 10:01:04