Coo*_*oop 5 node.js express typescript jestjs next.js
我在 NextJS 中有一个带有中间件设置的 API 路由,如下所示:
/src/middleware/validateData/index.ts
import { NextApiRequest, NextApiResponse } from 'next';
import schema from './schema';
type Handler = (req: NextApiRequest, res: NextApiResponse) => void;
export default (handler: Handler) => {
return (req: NextApiRequest, res: NextApiResponse) => {
const { error } = schema.validate(req.body, { abortEarly: false });
if (error) res.status(400).send(error);
else handler(req, res);
};
};
Run Code Online (Sandbox Code Playgroud)
/src/api/foo.ts
import { NextApiRequest, NextApiResponse } from 'next';
import validateData from '../../middleware/validateData';
const foo = (req: NextApiRequest, res: NextApiResponse) => {
res.send('It works!');
};
export default validateData(foo);
Run Code Online (Sandbox Code Playgroud)
模式引用是@hapi/joi用于验证req.body数据的模式,我没有包含它,因为我认为它与问题无关。
我想知道如何自行对中间件进行单元测试?据我所知,这大约是:
/src/middleware/validateData/index.test.ts
import validateData from './validateData';
describe('validateData', () => {
const mockHandler = jest.fn();
const mockReq = {
body: '',
};
const mockRes = {
send: jest.fn(),
};
it('responds with error', () => {
validateData(mockHandler)(mockReq, mockRes);
expect(mockRes.send).toHaveBeenCalled();
});
});
Run Code Online (Sandbox Code Playgroud)
但是使用这种技术,我首先得到类型错误,mockReq并且mockRes缺少属性(所以我想我需要正确地模拟它们,但不确定如何),其次测试失败,因为res.send尽管传递了无效的主体数据,但测试失败了。
有人知道如何正确模拟和测试这个吗?
我觉得我的方法是完全错误的,因为我想检查整个响应(状态代码、收到的特定消息等)。是启动模拟服务器并实际模拟 api 调用之类的唯一方法吗?
next-test-api-route-handler是一个包(免责声明:我创建了!),它简化了为 Next API 路由编写单元测试的过程。它test-listen在底层使用来生成真正的 HTTP 响应。例如:
import validateData from './validateData';
import { testApiHandler } from 'next-test-api-route-handler';
describe('validateData', () => {
it('responds with error', async () => {
await testApiHandler({
handler: validateData((_, res) => res.send('It works!')),
test: async ({ fetch }) => {
// Returns a real ServerResponse instance
const res = await fetch();
// Hence, res.status == 200 if send(...) was called above
expect(res.status).toBe(200);
// We can even inspect the data that was returned
expect(await res.text()).toBe('It works!');
}
});
});
});
Run Code Online (Sandbox Code Playgroud)
这样,您还可以在测试中直接检查获取的响应对象。更好的是,您的 API 路由处理程序的功能与 Next.js 中的功能相同,因为它们传递的是实际的NextApiRequest 和 NextApiResponse实例,而不是 TypeScript 类型或模拟。
| 归档时间: |
|
| 查看次数: |
6481 次 |
| 最近记录: |