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

