如何借助Mock库基于Schema生成异常数据测试Web API错误场景?
刚好我之前做过类似的API错误场景测试,给你梳理一下可行的方案和规范流程~
推荐的Mock数据生成工具
首先给你推荐几个能同时生成正常/异常Mock数据的工具,适配不同技术栈:
- Faker.js + 自定义封装:Faker本身擅长生成符合真实场景的正常数据,你可以封装一层工具函数,针对指定字段注入错误逻辑(比如把邮箱改成
invalid-email、姓名加数字),灵活性很高。 - json-schema-faker + 错误修改器:它能直接基于JSON Schema生成合规的正常数据,搭配自定义函数可以快速修改指定字段,生成不符合规则的异常数据,适合用JSON Schema做校验的场景。
- Mongoose反向Mock工具:如果你的服务用Mongoose模型,可以利用模型的验证规则反向推导异常数据——比如针对
email字段生成不含@的字符串,针对phone生成带非数字的内容。 - Mockaroo:支持可视化定义Schema和异常规则(比如强制生成格式错误的邮箱),也提供API可以程序化调用生成数据,适合快速批量生成测试用例。
API错误场景测试的流程规范
这类测试的核心是覆盖所有字段的验证规则,并且和API返回的错误码/信息一一对应,推荐按以下流程来:
- 梳理所有字段的验证规则:先把用户服务每个字段的规则列全,比如:
- name:非空、长度2-50、仅允许字母和空格
- email:符合RFC格式、非空
- phone:10位数字、非空
- 为每个规则生成独立测试用例:每条验证规则对应一个错误场景,比如name为空、name含数字、邮箱无@符号等,避免用一个测试覆盖多个错误。
- 关联错误码与错误信息:测试时不仅要断言请求被拒绝,还要验证返回的错误码(比如
EMAIL_INVALID)和错误描述完全匹配预期,确保API的错误反馈符合设计。 - 模块化生成异常数据:写一个通用工具函数,接收正常Mock数据和错误配置(比如
{ field: 'email', errorType: 'no-at-sign' }),返回对应的异常数据,减少重复代码。 - 按逻辑分组测试用例:把测试用例按正常场景、字段错误场景分组,让代码结构更清晰,比如单独用一个
describe块包裹所有email相关的错误测试。
代码示例(基于json-schema-faker)
下面是结合你的代码改造的示例,用json-schema-faker生成数据,搭配自定义工具生成异常用例:
首先安装依赖:
npm install json-schema-faker faker should --save-dev
然后写Mock数据生成工具:
const jsf = require('json-schema-faker'); const faker = require('faker'); // 你的用户JSON Schema const userSchema = { type: 'object', properties: { name: { type: 'string', minLength: 2, maxLength: 50, pattern: '^[A-Za-z\\s]+$' }, email: { type: 'string', format: 'email' }, phone: { type: 'string', pattern: '^\\d{10}$' } }, required: ['name', 'email', 'phone'] }; // 生成正常用户数据 const generateValidUser = () => jsf.generate(userSchema); // 生成指定字段的异常数据 const generateInvalidUser = (field, errorType) => { const validUser = generateValidUser(); switch (field) { case 'name': if (errorType === 'too-short') validUser.name = 'A'; else if (errorType === 'has-numbers') validUser.name = `${faker.name.firstName()}123`; else if (errorType === 'empty') validUser.name = ''; break; case 'email': if (errorType === 'no-at') validUser.email = 'invalid-email.com'; else if (errorType === 'invalid-domain') validUser.email = 'user@.com'; break; case 'phone': if (errorType === 'non-numeric') validUser.phone = '123-abc-4567'; else if (errorType === 'wrong-length') validUser.phone = '12345'; break; default: throw new Error(`Unsupported error type for field: ${field}`); } return validUser; }; module.exports = { generateValidUser, generateInvalidUser };
最后是测试代码:
const app = require('./myapp'); const { generateValidUser, generateInvalidUser } = require('./user-mock-generator'); const should = require('should'); describe('users service', () => { // 正常场景测试 it('create method - should create user with valid data', () => { const validUser = generateValidUser(); return app.service('users') .create(validUser) .should.eventually.have.property('_id'); }); // Email错误场景分组 describe('create method - email validation errors', () => { it('should reject when email has no @ sign', () => { const invalidUser = generateInvalidUser('email', 'no-at'); return app.service('users') .create(invalidUser) .should.be.rejectedWith(Error, 'Invalid email format') .and.have.property('code', 'EMAIL_INVALID'); }); it('should reject when email has invalid domain', () => { const invalidUser = generateInvalidUser('email', 'invalid-domain'); return app.service('users') .create(invalidUser) .should.be.rejectedWith(Error, 'Invalid email domain') .and.have.property('code', 'EMAIL_DOMAIN_INVALID'); }); }); // Name错误场景分组 describe('create method - name validation errors', () => { it('should reject when name is too short', () => { const invalidUser = generateInvalidUser('name', 'too-short'); return app.service('users') .create(invalidUser) .should.be.rejectedWith(Error, 'Name must be at least 2 characters') .and.have.property('code', 'NAME_TOO_SHORT'); }); }); });
内容的提问来源于stack exchange,提问作者Neuwolferl
相关产品推荐
相关产品推荐

