如何用Chai校验返回Array<Movie>类型的Node.js API接口响应?
核心疑问解答
请问是否可以直接使用Typescript类型来校验API返回的响应数据?
不可以。Typescript的类型定义只存在于编译阶段,运行时会被完全擦除,chai作为运行时的断言库无法识别你在代码中定义的Movie类型,所以你尝试传入"Array<Movie>"作为类型参数的写法会直接报错。
可行的校验方案
- 方案1:纯chai手动遍历校验(无需额外依赖)
直接遍历返回的数组,对每一个元素的字段逐个做类型校验,示例代码如下:
// 先校验整体是数组 res.body.should.be.an("array"); // 遍历校验每个元素符合Movie结构 res.body.forEach(movie => { movie.should.be.an("object"); movie.should.have.property("id").that.is.a("number"); movie.should.have.property("year").that.is.a("number"); movie.should.have.property("rent_number").that.is.a("number"); movie.should.have.property("title").that.is.a("string"); movie.should.have.property("author").that.is.a("string"); movie.should.have.property("editor").that.is.a("string"); })
这个方案不需要引入额外依赖,适合字段少、校验逻辑简单的场景。
- 方案2:使用chai-json-schema插件批量校验
如果字段较多或者不想手写遍历逻辑,可以使用chai-json-schema插件,通过JSON Schema定义Movie的结构,一次性校验整个数组:
首先安装依赖:
npm install chai-json-schema --save-dev
然后在测试代码中引入使用:
const chai = require('chai'); chai.use(require('chai-json-schema')); // 定义Movie的JSON Schema const movieSchema = { type: 'object', required: ['id', 'year', 'rent_number', 'title', 'author', 'editor'], properties: { id: { type: 'number' }, year: { type: 'number' }, rent_number: { type: 'number' }, title: { type: 'string' }, author: { type: 'string' }, editor: { type: 'string' } } }; // 定义返回数组的Schema const movieArraySchema = { type: 'array', items: movieSchema }; // 断言校验 res.body.should.be.jsonSchema(movieArraySchema);
- 方案3:使用运行时类型库复用类型定义
如果希望TS类型定义和运行时校验逻辑保持一致,避免两边重复编写,可以使用zod、io-ts这类运行时类型校验库,先定义运行时校验结构,再从结构导出TS类型:
以zod为例,安装依赖:
npm install zod --save
代码示例:
import { z } from 'zod'; // 定义运行时校验结构 const MovieSchema = z.object({ id: z.number(), year: z.number(), rent_number: z.number(), title: z.string(), author: z.string(), editor: z.string() }); // 导出TS类型,和你之前手写的Movie类型完全等价 type Movie = z.infer<typeof MovieSchema>; // 校验接口返回值,直接校验整个数组 const result = MovieSchema.array().safeParse(res.body); if (!result.success) { // 校验不通过时抛出错误 throw new Error(`返回数据不符合Movie数组结构:${result.error}`); } // 校验通过后result.data就是类型为Array<Movie>的数据
内容的提问来源于stack exchange,提问作者John
相关产品推荐
相关产品推荐

