我在控制器中有一个方法,如下所示:
import { calcu } from '../services/myServices';
export const getProduct = (req, res, next) => {
try {
const { type } = req.params;
const { id, productCode } = req.body;
if (!id || !productCode) {
res.status(400).json({ error: { message: 'Id or productCode is required' } });
} else {
switch (type.toUpperCase()) {
case 'X':
try {
const result = calcu(id, productCode);
res.status(200).json(result);
} catch (err) {
res.status(400).json({ error: { message: err.message } });
}
break;
default:
res.status(400).json({ error: { message: `type ${type} is not support` } });
}
}
} catch (err) {
next(err);
}
};
在这种情况下,这是我的单元测试代码:
import { getProduct } from './quotationController';
describe('Controller', () => {
let json, res, status;
test('Should return message error if the id or productCode is missing', () => {
const req = {
body: { id: "1111" },
param: { type: "qqqqq" }
};
const next = err => err.message;
const result = getProduct(req, res, next);
//expect(result).toBe(undefined);
expect(result).toEqual({
code: 400,
message: 'Id or productCode is required'
});
});
})
运行单元测试代码时出现错误:
结果不确定。
答案 0 :(得分:0)
这是单元测试解决方案:
controller.js
:
import { calcu } from './service';
export const getProduct = (req, res, next) => {
try {
const { type } = req.params;
const { id, productCode } = req.body;
if (!id || !productCode) {
res.status(400).json({ error: { message: 'Id or productCode is required' } });
} else {
switch (type.toUpperCase()) {
case 'X':
try {
const result = calcu(id, productCode);
res.status(200).json(result);
} catch (err) {
res.status(400).json({ error: { message: err.message } });
}
break;
default:
res.status(400).json({ error: { message: `type ${type} is not support` } });
}
}
} catch (err) {
next(err);
}
};
service.js
:(模拟)
export function calcu(id, code) {
return id + code;
}
controller.test.js
:
import { getProduct } from './controller';
import { calcu } from './service';
jest.mock('./service.js', () => ({ calcu: jest.fn() }));
describe('Controller', () => {
let mRes;
let mNext;
beforeEach(() => {
mRes = { status: jest.fn().mockReturnThis(), json: jest.fn() };
mNext = jest.fn();
});
afterEach(() => {
jest.resetAllMocks();
});
test('Should return message error if the id or productCode is missing', () => {
const mReq = { body: { id: '1111' }, params: { type: 'qqqqq' } };
getProduct(mReq, mRes, mNext);
expect(mRes.status).toBeCalledWith(400);
expect(mRes.status().json).toBeCalledWith({ error: { message: 'Id or productCode is required' } });
});
test('should call next when error happens', () => {
const mReq = {};
getProduct(mReq, mRes, mNext);
expect(mNext).toBeCalledWith(expect.any(Error));
});
test('should return message error if type is not support', () => {
const mReq = { params: { type: 'qqqqq' }, body: { id: '1111', productCode: '22' } };
getProduct(mReq, mRes, mNext);
expect(mRes.status).toBeCalledWith(400);
expect(mRes.status().json).toBeCalledWith({ error: { message: `type ${mReq.params.type} is not support` } });
});
test('should return message error if calcu errors', () => {
const mReq = { params: { type: 'x' }, body: { id: '1111', productCode: '22' } };
const mError = new Error('calc error');
calcu.mockImplementationOnce(() => {
throw mError;
});
getProduct(mReq, mRes, mNext);
expect(calcu).toBeCalledWith('1111', '22');
expect(mRes.status).toBeCalledWith(400);
expect(mRes.status().json).toBeCalledWith({ error: { message: mError.message } });
});
test('should return correct calc result', () => {
const mReq = { params: { type: 'x' }, body: { id: '1111', productCode: '22' } };
calcu.mockReturnValueOnce({ data: 'fake data' });
getProduct(mReq, mRes, mNext);
expect(calcu).toBeCalledWith('1111', '22');
expect(mRes.status).toBeCalledWith(200);
expect(mRes.status().json).toBeCalledWith({ data: 'fake data' });
});
});
覆盖率100%的单元测试结果:
PASS src/stackoverflow/59508494/controller.test.js (7.379s)
Controller
✓ Should return message error if the id or productCode is missing (6ms)
✓ should call next when error happens (1ms)
✓ should return message error if type is not support (1ms)
✓ should return message error if calcu errors (2ms)
✓ should return correct calc result (2ms)
---------------|----------|----------|----------|----------|-------------------|
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s |
---------------|----------|----------|----------|----------|-------------------|
All files | 100 | 100 | 100 | 100 | |
controller.js | 100 | 100 | 100 | 100 | |
---------------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests: 5 passed, 5 total
Snapshots: 0 total
Time: 8.731s, estimated 10s
源代码:https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/59508494