REST API NODEJS 中的玩笑找不到控制器的正确测试.js



我为物流控制创建了一个 REST API,可以在其中创建卡车司机,根据他是否加载、日期等过滤搜索特定司机。

现在要完成我的项目,我正在尝试为此导出模块创建一个单元测试,但找不到正确的解决方案:

const Driver = require('../models/models.js');
// Create and Save a new driver
exports.create = (req, res) => {
const { oLongitude, oLatitude } = req.body;
const { dLongitude, dLatitude } = req.body;
// Validade request
if (!Object.keys(req.body).length) {
return res.status(400).json({
message: "Form content can not be empty"
});
}
//Create a driver
const driver = new Driver({
name: req.body.name,
age: req.body.age,
gender: req.body.gender,
veichle: req.body.veichle,
cnhType: req.body.cnhType,
loaded: req.body.loaded,
truckType: req.body.truckType,
origin: {
type: 'Point',
coordinates: [oLongitude, oLatitude]
},
destination: {
type: 'Point',
coordinates: [dLongitude, dLatitude]
},
date: req.body.date
});
//Save driver in the database
driver.save()
.then(data => {
res.json(data);
}).catch(err => {
res.status(500).send({
message: err.message || "Some error ocurred while creating the driver."
});
});
};

这是我已经尝试过的:

const httpMocks = require('node-mocks-http');
const { create } = require('../app/controllers/controller.js');
describe('create', () => {
test('should create stuff', () => {
const request = httpMocks.createRequest({
method: 'POST',
url: '/create'
});
const response = httpMocks.createResponse();
create(request, response, (err) => {
expect(err).toBeFalsy();
});
const { property } = JSON.parse(response._getData());
expect(property).toBe({
name: "Antonio dos Santos",
age: "27",
gender: "masculino",
veichle: "nao",
cnhType: "D",
loaded: "nao",
truckType: 2,
oLongitude: -46.9213486,
oLatitude: -23.7341936,
dLongitude: -46.9057519,
dLatitude: -23.8529033,
date: "08/02/2020"
});
});
});

下面是单元测试解决方案:

controller.js

const Driver = require('./models.js');
exports.create = (req, res) => {
const { oLongitude, oLatitude } = req.body;
const { dLongitude, dLatitude } = req.body;
if (!Object.keys(req.body).length) {
return res.status(400).json({
message: 'Form content can not be empty',
});
}
const driver = new Driver({
name: req.body.name,
age: req.body.age,
gender: req.body.gender,
veichle: req.body.veichle,
cnhType: req.body.cnhType,
loaded: req.body.loaded,
truckType: req.body.truckType,
origin: {
type: 'Point',
coordinates: [oLongitude, oLatitude],
},
destination: {
type: 'Point',
coordinates: [dLongitude, dLatitude],
},
date: req.body.date,
});
return driver
.save()
.then((data) => {
res.json(data);
})
.catch((err) => {
res.status(500).send({
message: err.message || 'Some error ocurred while creating the driver.',
});
});
};

models.js

function Driver() {
async function save() {
return 'real implementation';
}
return {
save,
};
}
module.exports = Driver;

controller.test.js

const { create } = require('./controller');
const Driver = require('./models.js');
jest.mock('./models', () => {
const mDriver = { save: jest.fn() };
return jest.fn(() => mDriver);
});
describe('60189651', () => {
afterEach(() => {
jest.clearAllMocks();
});
it('should create driver and send to client side', () => {
expect.assertions(3);
const mReq = {
body: {
name: 'name',
age: 23,
gender: 'male',
veichle: 'BMW',
cnhType: 'type',
loaded: true,
truckType: 'truckType',
oLatitude: 1,
oLongitude: 1,
dLongitude: 2,
dLatitude: 2,
date: '2020',
},
};
const mRes = { json: jest.fn() };
const mDriver = new Driver();
mDriver.save.mockResolvedValueOnce('saved driver');
return create(mReq, mRes).then(() => {
expect(Driver).toBeCalledWith({
name: 'name',
age: 23,
gender: 'male',
veichle: 'BMW',
cnhType: 'type',
loaded: true,
truckType: 'truckType',
origin: {
type: 'Point',
coordinates: [1, 1],
},
destination: {
type: 'Point',
coordinates: [2, 2],
},
date: '2020',
});
expect(mDriver.save).toBeCalledTimes(1);
expect(mRes.json).toBeCalledWith('saved driver');
});
});
it('should handle error if request body is empty', () => {
const mReq = { body: {} };
const mRes = { status: jest.fn().mockReturnThis(), json: jest.fn() };
create(mReq, mRes);
expect(mRes.status).toBeCalledWith(400);
expect(mRes.status(400).json).toBeCalledWith({ message: 'Form content can not be empty' });
});
it('should handle error if save driver failure', () => {
expect.assertions(4);
const mReq = {
body: {
name: 'name',
age: 23,
gender: 'male',
veichle: 'BMW',
cnhType: 'type',
loaded: true,
truckType: 'truckType',
oLatitude: 1,
oLongitude: 1,
dLongitude: 2,
dLatitude: 2,
date: '2020',
},
};
const mRes = { status: jest.fn().mockReturnThis(), send: jest.fn() };
const mDriver = new Driver();
const mError = new Error('database connection failure');
mDriver.save.mockRejectedValueOnce(mError);
return create(mReq, mRes).then(() => {
expect(Driver).toBeCalledWith({
name: 'name',
age: 23,
gender: 'male',
veichle: 'BMW',
cnhType: 'type',
loaded: true,
truckType: 'truckType',
origin: {
type: 'Point',
coordinates: [1, 1],
},
destination: {
type: 'Point',
coordinates: [2, 2],
},
date: '2020',
});
expect(mDriver.save).toBeCalledTimes(1);
expect(mRes.status).toBeCalledWith(500);
expect(mRes.status(500).send).toBeCalledWith({ message: mError.message });
});
});
});

带有覆盖率报告的单元测试结果:

PASS  stackoverflow/60189651/controller.test.js (6.724s)
60189651
✓ should create driver and send to client side (6ms)
✓ should handle error if request body is empty (2ms)
✓ should handle error if save driver failure (1ms)
---------------|---------|----------|---------|---------|-------------------
File           | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
---------------|---------|----------|---------|---------|-------------------
All files      |     100 |       75 |     100 |     100 |                   
controller.js |     100 |       75 |     100 |     100 | 39                
---------------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests:       3 passed, 3 total
Snapshots:   0 total
Time:        8.747s, estimated 9s

源代码:https://github.com/mrdulin/react-apollo-graphql-starter-kit/tree/master/stackoverflow/60189651

最新更新