Javascript 单元测试控制器使用Jest、NodeJS
我想检查一种情况,即某些路由正在调用正确的控制器useJestspecific(mock或spy) 对于单元测试,它是特定于案例的。有人可以帮我用笑话检查一下。我不需要什么验证 expect(状态代码或res对象)我需要检查是否调用了控制器。 谢谢 例如:Javascript 单元测试控制器使用Jest、NodeJS,javascript,node.js,unit-testing,express,jestjs,Javascript,Node.js,Unit Testing,Express,Jestjs,我想检查一种情况,即某些路由正在调用正确的控制器useJestspecific(mock或spy) 对于单元测试,它是特定于案例的。有人可以帮我用笑话检查一下。我不需要什么验证 expect(状态代码或res对象)我需要检查是否调用了控制器。 谢谢 例如: // todoController.js function todoController (req, res) { res.send('Hello i am todo controller') } // index.spec.js
// todoController.js
function todoController (req, res) {
res.send('Hello i am todo controller')
}
// index.spec.js
const express = require('express');
const request = require('request-promise');
const todoController = require('./todoController');
jest.mock('./todoController');
const app = express();
app.get('/todo', todoController)
test('If certain routes are calling the correct controller , controller should to have been called times one.', async() => {
await request({url: 'http://127.0.0.1/todo'})
expect(todoController).toHaveBeenCalledTimes(1);
})
实际上,如果你搜索,有很多参考文献 在下面,我将分享一些我知道的方法 使用模拟请求/响应测试Express应用程序的一个重大概念性飞跃是理解如何模拟链式应用程序 API例如
res.status(200).json({foo:'bar})
首先,您可以创建某种拦截器,这是通过从其每个方法返回res实例来实现的:
// util/interceptor.js
module.exports = {
mockRequest: () => {
const req = {}
req.body = jest.fn().mockReturnValue(req)
req.params = jest.fn().mockReturnValue(req)
return req
},
mockResponse: () => {
const res = {}
res.send = jest.fn().mockReturnValue(res)
res.status = jest.fn().mockReturnValue(res)
res.json = jest.fn().mockReturnValue(res)
return res
},
// mockNext: () => jest.fn()
}
Express user land API基于中间件。以请求(通常称为req)、响应(通常称为res)和下一个(调用下一个中间件)为参数的中间件
然后你有这样的控制器:
// todoController.js
function todoController (req, res) {
if (!req.params.id) {
return res.status(404).json({ message: 'Not Found' });
}
res.send('Hello i am todo controller')
}
它们通过“挂载”到Express应用程序(app)实例(在app.js中)来消耗:
使用前面定义的mockRequest和mockResponse,然后我们将评估使用正确的负载({data})
调用res.send()
因此,在您的测试文件中:
// todo.spec.js
const { mockRequest, mockResponse } = require('util/interceptor')
const controller = require('todoController.js')
describe("Check method \'todoController\' ", () => {
test('should 200 and return correct value', async () => {
let req = mockRequest();
req.params.id = 1;
const res = mockResponse();
await controller.todoController(req, res);
expect(res.send).toHaveBeenCalledTimes(1)
expect(res.send.mock.calls.length).toBe(1);
expect(res.send).toHaveBeenCalledWith('Hello i am todo controller');
});
test('should 404 and return correct value', async () => {
let req = mockRequest();
req.params.id = null;
const res = mockResponse();
await controller.todoController(req, res);
expect(res.status).toHaveBeenCalledWith(404);
expect(res.json).toHaveBeenCalledWith({ message: 'Not Found' });
});
});
这是测试Express处理程序和中间件的唯一方法。另一种方法是启动Express服务器。很好的例子。您可以使用,这样您就不必自己实现mockRequest
和mockResponse
了。
// todo.spec.js
const { mockRequest, mockResponse } = require('util/interceptor')
const controller = require('todoController.js')
describe("Check method \'todoController\' ", () => {
test('should 200 and return correct value', async () => {
let req = mockRequest();
req.params.id = 1;
const res = mockResponse();
await controller.todoController(req, res);
expect(res.send).toHaveBeenCalledTimes(1)
expect(res.send.mock.calls.length).toBe(1);
expect(res.send).toHaveBeenCalledWith('Hello i am todo controller');
});
test('should 404 and return correct value', async () => {
let req = mockRequest();
req.params.id = null;
const res = mockResponse();
await controller.todoController(req, res);
expect(res.status).toHaveBeenCalledWith(404);
expect(res.json).toHaveBeenCalledWith({ message: 'Not Found' });
});
});