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

Node项目中如何用Sinon生成带随机值的Stub测试数据

在Node.js中用Sinon生成随机Stub数据进行API测试

需求说明

在Node项目中使用Sinon编写API测试用例时,需要对数据库查询的Stub返回数据进行改造,将原本静态的name(字符串)、age(数字)、DOB(日期)字段替换为随机生成的值。

当前实现代码(含语法问题)

const stubData = {
      name = "XYZ", // 错误:对象属性应使用冒号而非等号
      age = 19,
      DOB = "2004-12-08"
}

DBStub = sinon.stub(mongoDB.protype, "findbyId") // 错误:prototype拼写错误,findById应为驼峰命名

DBStub.withargs("2").resolves(stubData) // 错误:withArgs首字母需大写

const res = await request(app)
            .get('/api/data')
            .set('Accept', 'application/json')
            .expect('Content-Type', /json/)
            .expect(200);

const returnedBank = res.body;
expect(returnedBank).toMatchObject({ id: '2', status: 'success' });

实现方案

可以通过原生JavaScript编写简单的随机生成函数,无需额外依赖;也可选择第三方库简化开发。

1. 原生JS实现随机生成

先编写工具函数生成各字段的随机值:

// 生成随机姓名(从预设姓名库选取)
const getRandomName = () => {
  const firstNames = ['Alice', 'Bob', 'Charlie', 'Diana', 'Ethan'];
  const lastNames = ['Smith', 'Johnson', 'Williams', 'Brown', 'Jones'];
  return `${firstNames[Math.floor(Math.random() * firstNames.length)]} ${lastNames[Math.floor(Math.random() * lastNames.length)]}`;
};

// 生成18-60之间的随机年龄
const getRandomAge = () => Math.floor(Math.random() * 43) + 18;

// 生成1960-2005之间的随机日期,格式为YYYY-MM-DD
const getRandomDOB = () => {
  const start = new Date(1960, 0, 1);
  const end = new Date(2005, 11, 31);
  const randomDate = new Date(start.getTime() + Math.random() * (end.getTime() - start.getTime()));
  return randomDate.toISOString().split('T')[0];
};

2. 修改后的完整测试代码

整合随机函数并修正原代码的语法问题:

const sinon = require('sinon');
const request = require('supertest');
const { expect } = require('chai');

// 随机生成工具函数
const getRandomName = () => {
  const firstNames = ['Alice', 'Bob', 'Charlie', 'Diana', 'Ethan'];
  const lastNames = ['Smith', 'Johnson', 'Williams', 'Brown', 'Jones'];
  return `${firstNames[Math.floor(Math.random() * firstNames.length)]} ${lastNames[Math.floor(Math.random() * lastNames.length)]}`;
};

const getRandomAge = () => Math.floor(Math.random() * 43) + 18;

const getRandomDOB = () => {
  const start = new Date(1960, 0, 1);
  const end = new Date(2005, 11, 31);
  const randomDate = new Date(start.getTime() + Math.random() * (end.getTime() - start.getTime()));
  return randomDate.toISOString().split('T')[0];
};

// 测试用例
describe('API /api/data', () => {
  it('should return success with random stub data', async () => {
    // 生成随机Stub数据
    const stubData = {
      name: getRandomName(),
      age: getRandomAge(),
      DOB: getRandomDOB()
    };

    // 创建并配置Sinon Stub
    const DBStub = sinon.stub(mongoDB.prototype, "findById");
    DBStub.withArgs("2").resolves(stubData);

    // 发起请求并断言
    const res = await request(app)
      .get('/api/data')
      .set('Accept', 'application/json')
      .expect('Content-Type', /json/)
      .expect(200);

    const returnedBank = res.body;
    expect(returnedBank).toMatchObject({ id: '2', status: 'success' });
    // 可选:验证随机字段的格式合法性
    expect(typeof returnedBank.name).to.equal('string');
    expect(typeof returnedBank.age).to.equal('number');
    expect(returnedBank.DOB).to.match(/^\d{4}-\d{2}-\d{2}$/);

    // 恢复Stub避免影响其他测试
    DBStub.restore();
  });
});

可选:使用第三方库简化随机生成

如果允许引入依赖,可使用@faker-js/faker生成更贴近真实场景的随机数据:

npm install @faker-js/faker --save-dev

替换工具函数部分:

const { faker } = require('@faker-js/faker');

const getRandomName = () => faker.person.fullName();
const getRandomAge = () => faker.number.int({ min: 18, max: 60 });
const getRandomDOB = () => faker.date.birthdate({ min: 18, max: 60, mode: 'age' }).toISOString().split('T')[0];

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 16:43:16