如何用Jest测试分组函数返回的正确对象?(返回[Function Anonymous]问题)
Jest验证分组函数失败的解决方法及最佳实践
问题背景
我用Lodash实现了一个分组函数,逻辑是过滤指定属性不为null的对象,再按该属性分组:
const sort = (pets, attribute) => _(pets) .filter(pet => _.get(pet, attribute) !== null) .groupBy(attribute) .value()
测试数据如下:
const pets= [{ id: 1, name: 'snowy', }, { id: 2, name: 'quacky', }, { id: 3, name: 'snowy', age: 5, }, { id: null, name: null, age: null } ] const attribute = 'name'
执行sort(pets, attribute)后预期返回:
{ snowy: [ { id: 1, name: 'snowy' }, { id: 3, name: 'snowy', age: 5} ], quacky: [ { id: 2, name: 'quacky' } ] }
但我写的Jest测试代码执行失败:
const res = sort(users,key) expect(res).toEqual( expect.arrayContaining([ expect.objectContaining({'snowy' : [ { id: 1, name: 'snowy' }, { id: 3, name: 'snowy', age: 5 } ]}, expect.objectContaining({'quacky' : [ { id: 2, name: 'quacky' } ]})) ]) )
错误信息显示:
Expected: ArrayContaining [ObjectContaining {"snowy": [{"id": 1, "name": "snowy"}, {"age": 5, "id": 3, "name": "snowy"}]}] Received: [Function anonymous]
错误原因分析
- 变量名错误:测试代码中使用了未定义的
users和key,而非正确的pets和attribute,导致函数执行异常。 - 断言类型不匹配:分组函数返回的是对象,但测试中误用了
expect.arrayContaining(用于断言数组),完全不符合返回值类型。 - 断言结构错误:
expect.objectContaining的嵌套逻辑错误,不需要将对象包裹在数组断言中。
正确的Jest测试代码
针对分组函数的返回值类型,有两种常用的断言方式:
方式1:直接断言完整对象结构
适合返回结果明确、结构固定的场景:
test('按name属性正确分组并过滤null值', () => { const pets = [{ id: 1, name: 'snowy', }, { id: 2, name: 'quacky', }, { id: 3, name: 'snowy', age: 5, }, { id: null, name: null, age: null }]; const attribute = 'name'; const result = sort(pets, attribute); expect(result).toEqual({ snowy: [ { id: 1, name: 'snowy' }, { id: 3, name: 'snowy', age: 5 } ], quacky: [ { id: 2, name: 'quacky' } ] }); });
方式2:部分匹配断言
适合只需要验证关键属性,忽略其他细节的场景:
test('分组结果包含指定键及对应内容', () => { const pets = [/* 测试数据同上 */]; const attribute = 'name'; const result = sort(pets, attribute); // 验证snowy分组的内容 expect(result).toHaveProperty('snowy', expect.arrayContaining([ expect.objectContaining({ id: 1, name: 'snowy' }), expect.objectContaining({ id: 3, name: 'snowy' }) ])); // 验证quacky分组的内容 expect(result).toHaveProperty('quacky', expect.arrayContaining([ expect.objectContaining({ id: 2, name: 'quacky' }) ])); // 验证name为null的项被过滤 expect(result).not.toHaveProperty(null); });
分组函数的最佳测试方法
为了确保函数的鲁棒性,需要覆盖多种场景:
- 正常分组场景:验证多个相同属性值的对象被正确归为一组
- 过滤逻辑验证:确认属性值为
null的对象被排除 - 边界场景测试:
- 传入空数组,返回空对象
- 传入不存在的属性,验证分组行为(当前函数会将属性不存在的项分到
undefined键下) - 传入属性值为
undefined的对象,验证是否被保留(当前函数逻辑中undefined !== null,所以会被保留)
- 单一对象场景:传入单个有效对象,返回对应键的数组
示例测试用例:
test('传入空数组返回空对象', () => { expect(sort([], 'name')).toEqual({}); }); test('传入不存在的属性,将所有项分组到undefined键下', () => { const pets = [{ id: 1 }, { id: 2 }]; expect(sort(pets, 'nonexistent')).toEqual({ undefined: [ { id: 1 }, { id: 2 } ] }); }); test('属性值为undefined的项会被保留并分组', () => { const pets = [{ id: 1, name: undefined }, { id: 2 }]; expect(sort(pets, 'name')).toEqual({ undefined: [ { id: 1, name: undefined }, { id: 2 } ] }); });
内容的提问来源于stack exchange,提问作者Daichi
相关产品推荐
相关产品推荐

