基于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
相关产品推荐
相关产品推荐

