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

基于Jasmine/Expect实现对象键校验:无指定键或键值匹配特定值

嘿,这个需求我之前刚好碰到过,下面给你分享Jasmine和Expect(比如Jest的expect)两种场景下的实现方案,分自定义匹配器(推荐复用)和原生匹配器组合两种方式:

Jasmine 实现方案

方案一:自定义匹配器(推荐)

自定义匹配器的好处是可以在多个测试用例里复用,而且错误提示更清晰。我们可以写一个toBeAbsentOrEqualTo匹配器,逻辑就是:要么对象没有指定键,要么键存在时值等于预期。

// 在测试文件的 beforeEach 里注册自定义匹配器
beforeEach(() => {
  jasmine.addMatchers({
    toBeAbsentOrEqualTo: function(util, customEqualityTesters) {
      return {
        compare: function(actualObj, targetKey, expectedValue) {
          const result = {};
          
          // 检查对象是否不包含目标键
          if (!Object.prototype.hasOwnProperty.call(actualObj, targetKey)) {
            result.pass = true;
            result.message = `✅ 对象没有键 '${targetKey}',符合要求`;
          } else {
            // 键存在时,校验值是否匹配
            result.pass = util.equals(actualObj[targetKey], expectedValue, customEqualityTesters);
            if (result.pass) {
              result.message = `✅ 对象键 '${targetKey}' 的值等于预期 ${JSON.stringify(expectedValue)}`;
            } else {
              result.message = `❌ 对象键 '${targetKey}' 的值是 ${JSON.stringify(actualObj[targetKey])},不等于预期 ${JSON.stringify(expectedValue)}`;
            }
          }
          
          return result;
        }
      };
    }
  });
});

// 测试用例示例
describe('对象键校验', () => {
  it('当键不存在时通过校验', () => {
    const user = { name: 'Kenny' };
    expect(user).toBeAbsentOrEqualTo('age', 28);
  });

  it('当键存在且值匹配时通过校验', () => {
    const user = { name: 'Kenny', age: 28 };
    expect(user).toBeAbsentOrEqualTo('age', 28);
  });

  it('当键存在但值不匹配时失败', () => {
    const user = { name: 'Kenny', age: 25 };
    expect(user).toBeAbsentOrEqualTo('age', 28);
  });
});

方案二:原生匹配器组合

如果不想自定义匹配器,也可以用Jasmine原生的expect.or和objectContaining来组合实现:

describe('对象键校验', () => {
  it('验证键不存在或值匹配', () => {
    const user = { name: 'Kenny' };
    const expectedAge = 28;
    
    expect(user).toEqual(
      expect.or(
        // 情况1:对象不包含目标键
        expect.not.objectContaining({ age: expect.anything() }),
        // 情况2:对象包含目标键且值匹配
        expect.objectContaining({ age: expectedAge })
      )
    );
  });
});
Expect(Jest)实现方案

如果用的是Jest的expect库,同样可以自定义匹配器,逻辑和Jasmine类似:

// 注册自定义匹配器
expect.extend({
  toBeAbsentOrEqualTo(receivedObj, targetKey, expectedValue) {
    if (!Object.prototype.hasOwnProperty.call(receivedObj, targetKey)) {
      return {
        pass: true,
        message: () => `✅ 对象没有键 '${targetKey}',符合要求`
      };
    }
    
    const pass = this.equals(receivedObj[targetKey], expectedValue);
    if (pass) {
      return {
        pass: true,
        message: () => `✅ 对象键 '${targetKey}' 的值等于预期 ${this.utils.printExpected(expectedValue)}`
      };
    } else {
      return {
        pass: false,
        message: () => `❌ 对象键 '${targetKey}' 的值是 ${this.utils.printReceived(receivedObj[targetKey])},不等于预期 ${this.utils.printExpected(expectedValue)}`
      };
    }
  }
});

// 测试用例示例
test('键不存在时通过', () => {
  const user = { name: 'Kenny' };
  expect(user).toBeAbsentOrEqualTo('age', 28);
});

test('键存在且值匹配时通过', () => {
  const user = { name: 'Kenny', age: 28 };
  expect(user).toBeAbsentOrEqualTo('age', 28);
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 04:18:41