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

如何在Postman集合变量中存储函数并解决校验报错

问题描述

我希望重构重复代码并将其存储到Postman集合变量中,即使仅重复一次也想消除冗余。箭头函数形式的parseMillisecondsIntoReadableTime可正常运行,将其挂载到Object.prototype后调用也正常,但执行单元测试时出现schema校验错误:

Response schema validation successful | Error: schema is invalid: data.properties['metadata'].properties['parseMillisecondsIntoReadableTime'] should be object,boolean

此前322个单元测试全部正常,仅在尝试使用该存储函数后出现问题。

相关代码片段

箭头函数实现

const parseMillisecondsIntoReadableTime = milliseconds => {
    // 从传入的毫秒数计算小时(h)、分钟(m)、秒(s),返回类似"0h 29m 59s"的字符串
    const h = milliseconds / (1000 * 60 * 60);
    const m = (milliseconds % (1000 * 60 * 60)) / (1000 * 60);
    const s = (milliseconds % (1000 * 60)) / 1000;
    return parseInt(h) + 'h ' + parseInt(m) + 'm ' + parseInt(s) + 's';
};

挂载到Object原型的实现

Object.prototype.parseMillisecondsIntoReadableTime = function(milliseconds) {
    // 同上述箭头函数逻辑
    const h = milliseconds / (1000 * 60 * 60);
    const m = (milliseconds % (1000 * 60 * 60)) / (1000 * 60);
    const s = (milliseconds % (1000 * 60)) / 1000;
    return parseInt(h) + 'h ' + parseInt(m) + 'm ' + parseInt(s) + 's';
};

正常调用代码

let obj = {};
const timeToExpire = obj.parseMillisecondsIntoReadableTime(pm.collectionVariables.get('access_token_expiry') - new Date());
console.log('access_token valid for: ' + timeToExpire);

失败的测试代码

pm.test("Response schema validation successful", () => {
   const responseData = pm.response.json();

   const successSchema = JSON.parse(pm.collectionVariables.get("successSchema"));
   pm.expect(require("ajv")().validate(successSchema, responseData)).to.be.true;
});

SuccessSchema结构

const successSchema = {
    type: "object",
    properties: {
        metadata: {
            type: "object",
            properties: {
                status: { type: "string" }
            },
            required: ["status"]
        },
        data: {
            type: "object",
            properties: {
                brandName: { type: "string" },
                goodsSupplierNumber: { type: "string" },
                supplierNumber: { type: "string" }
            },
            required: ["brandName", "goodsSupplierNumber", "supplierNumber"]
        },
        errors: {
            type: "array",
            items: {
                type: "object",
                properties: {
                    code: { type: "string" },
                    message: { type: "string" }
                },
                required: ["code", "message"]
            }
        }
    },
    required: ["metadata", "data", "errors"]
};
pm.collectionVariables.set("successSchema", JSON.stringify(successSchema));
问题原因与解决方案

问题原因

给Object.prototype添加自定义方法后,AJV默认会遍历对象的所有属性(包括原型链上的属性)。当校验接口返回的metadata对象时,AJV会把原型链上的parseMillisecondsIntoReadableTime方法当成metadata的属性,但你的Schema中metadata只定义了status字段,因此触发校验错误。

解决方案

方案1:避免修改Object原型,直接将函数存入集合变量

不要污染全局原型,把函数以字符串形式存储到集合变量,调用时通过Function构造函数实例化:

// 存储函数到集合变量(可在集合前置脚本中执行)
pm.collectionVariables.set("parseMillisecondsIntoReadableTime", `
function(milliseconds) {
    const h = milliseconds / (1000 * 60 * 60);
    const m = (milliseconds % (1000 * 60 * 60)) / (1000 * 60);
    const s = (milliseconds % (1000 * 60)) / 1000;
    return parseInt(h) + 'h ' + parseInt(m) + 'm ' + parseInt(s) + 's';
}
`);

// 调用函数时
const parseFunc = new Function(`return ${pm.collectionVariables.get('parseMillisecondsIntoReadableTime')}`)();
const timeToExpire = parseFunc(pm.collectionVariables.get('access_token_expiry') - new Date());
console.log('access_token valid for: ' + timeToExpire);

方案2:修改AJV配置,仅校验对象自身属性

如果坚持使用原型方法,可以在初始化AJV时开启ownProperties选项,让AJV只校验对象自身的属性,忽略原型链上的属性:

pm.test("Response schema validation successful", () => {
   const responseData = pm.response.json();
   const successSchema = JSON.parse(pm.collectionVariables.get("successSchema"));
   // 配置AJV仅校验对象自身属性
   const ajv = require("ajv")({ ownProperties: true });
   pm.expect(ajv.validate(successSchema, responseData)).to.be.true;
});

方案3:使用无原型对象(局限性较大)

如果接口返回的metadata是你自己构造的,可以用Object.create(null)创建无原型的对象,这样原型链上的方法不会被遍历到,但此方案仅适用于你能控制responseData结构的场景,对接口返回的原始数据无效。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 06:00:19