JavaScript单元测试如何正确Mock数据对象解决filter未定义错误
单元测试报错根因
你遇到的两类报错本质是Mock数据结构和业务代码的实际访问层级不匹配,对应原因非常明确:
- 触发“无法读取undefined的filter属性”:业务代码实际是在
response.data._embedded字段上调用filter方法,但你最初的Mock把数组直接放在了data层级,data对象本身不存在_embedded字段,取值为undefined时自然无法调用filter - 触发“filter不是函数”:你补充
_embedded字段时,如果给该字段赋的值是chance.object()生成的普通对象、而非数组,普通对象本身没有原生的Array.prototype.filter方法,就会抛出该错误
注意:你的业务代码存在一个作用域问题——handler解构入参拿到的是
{query},但内部取workType时写的是searchParams.get('workType'),当前作用域内并没有定义searchParams变量,测试时要确保workType的取值逻辑和入参query对齐,否则代码根本走不到filter分支。
正确的Mock构造方式
要让filter逻辑正常运行,你需要完全对齐业务代码的访问链路搭建Mock,核心满足三个要求:
- Mock的axios返回结构和真实axios响应一致:外层结构为
{ data: 具体业务数据 } - 业务数据层必须包含
_embedded字段,且该字段严格为数组类型,才能正常调用filter方法 - 数组内的每个订阅对象,必须补齐filter回调读取的嵌套结构:也就是
systemProperties.workType属性,否则filter执行时会因为读取嵌套属性为undefined触发新的报错
可直接复用的Mock示例
替换测试文件中原来的getSubscriptionsResponse定义即可:
const workType = chance.word(); // 匹配业务逻辑的Mock响应 const getSubscriptionsResponse = { data: { // 数组类型的_embedded字段,自带filter方法 _embedded: [ { // 补齐filter逻辑需要的嵌套结构 systemProperties: { workType: workType // 匹配过滤条件的订阅项 }, id: chance.guid(), subscriptionName: chance.sentence() }, { systemProperties: { workType: 'OtherWorkType' // 不匹配普通workType过滤规则的项 }, id: chance.guid(), subscriptionName: chance.sentence() }, { systemProperties: {} // 无workType属性的项,对应Unknown分支的测试场景 , id: chance.guid(), subscriptionName: chance.sentence() } ], // 可根据实际业务补充其他data字段,不影响逻辑执行 pagination: { pageNo: 0, pageSize: 20, total: 3 } } };
高频踩坑提醒
- 不要把普通对象直接赋值给
_embedded字段:错误写法比如_embedded: chance.object(),生成的键值对对象不是数组,不存在filter方法 - 不要漏写嵌套属性:如果没给数组元素加
systemProperties结构,就算_embedded是合法数组,filter执行时读取subscriptions.systemProperties.workType依然会报undefined错误 - 测试时不要只验证axios的调用参数:要在
await handler(...)调用后接收返回值,针对不同的workType入参场景,断言返回的_embedded数组是否符合预期的过滤规则,覆盖三个核心分支:无workType入参时不做过滤、普通workType入参时匹配对应类型的订阅、Unknown值入参时过滤出无workType属性的订阅。
内容的提问来源于stack exchange,提问作者Mike Sassatelli
相关产品推荐
相关产品推荐

