我正在使用Jest作为我的单元测试框架。我正在尝试模拟npm的第三部分“请求”并执行了我的测试用例,但是我收到了并且测试失败了
expect(jest.fn()).toHaveBeenCalledWith(...expected)
Expected: 200
Number of calls: 0
以下是我的代码:
spec.js
jest.mock('request', () => ({
post: jest.fn()
}));
const request = require('request');
const mockRequest = (reqData) => {
return {
params: reqData.params? reqData.params:{} ,
body: reqData.body?reqData.body:{},
headers: reqData.headers?reqData.headers:{}
};
};
const mockResponse = () => {
const res = {};
res.status = jest.fn().mockReturnValue(res);
res.json = jest.fn().mockReturnValue(res);
res.send = jest.fn().mockReturnValue(res);
return res;
};
describe("Test suite for controller", () => {
test("should return true for successful validation",async () => {
request.post.mockResolvedValue({
"key1":"value1",
"key2":"value2"
});
const req = mockRequest();
const res = mockResponse();
const Ctrl = require('../../controllers/ctrl')
await Ctrl.validate(req, res);
//const result = await res1.json();
expect(res.status).toHaveBeenCalledWith(200);
});
});
Ctrl.js
const request = require('request');
module.exports = {
async validate(req, res) {
var postBody = {
url: url,
form: body,
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
};
await request.post(postBody, function (error, response, body) {
if (error) {
return res.status(200).json({ result: "false" });
} else {
return res.status(200).json({ result: "true" });
}
});
});
}
请分享您的想法。谢谢。
答案 0 :(得分:0)
await
的回调中使用request.post
,只需选择其中之一即可。不要一起使用。选择Promise或错误优先的回调来处理异步代码。request.post
的实现,以便可以在测试用例中获得回调函数。然后,您可以将成功的响应或错误传递给此回调并测试回调的代码逻辑。res
对象的链方法。这是单元测试解决方案:
ctrl.js
:
const request = require('request');
module.exports = {
async validate(req, res) {
var postBody = {
url: 'url',
form: req.body,
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
};
request.post(postBody, function(error, response, body) {
if (error) {
return res.status(200).json({ result: 'false' });
} else {
return res.status(200).json({ result: 'true' });
}
});
},
};
ctrl.spec.js
:
const request = require('request');
const Ctrl = require('./ctrl');
jest.mock('request', () => ({
post: jest.fn(),
}));
describe('Test suite for controller', () => {
afterAll(() => {
jest.resetAllMocks();
});
test('should return true for successful validation', async () => {
request.post.mockImplementationOnce((body, callback) => {
callback(null);
});
const req = { body: {} };
const res = { status: jest.fn().mockReturnThis(), json: jest.fn() };
await Ctrl.validate(req, res);
expect(request.post).toBeCalledWith(
{
url: 'url',
form: {},
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
},
expect.any(Function),
);
expect(res.status).toHaveBeenCalledWith(200);
expect(res.json).toBeCalledWith({ result: 'true' });
});
test('should handle error for failed validation', async () => {
const mErr = new Error('network');
request.post.mockImplementationOnce((body, callback) => {
callback(mErr);
});
const req = { body: {} };
const res = { status: jest.fn().mockReturnThis(), json: jest.fn() };
await Ctrl.validate(req, res);
expect(request.post).toBeCalledWith(
{
url: 'url',
form: {},
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
},
expect.any(Function),
);
expect(res.status).toHaveBeenCalledWith(200);
expect(res.json).toBeCalledWith({ result: 'false' });
});
});
具有覆盖率报告的单元测试结果:
PASS src/stackoverflow/64311760/ctrl.spec.js (16.499s)
Test suite for controller
✓ should return true for successful validation (16ms)
✓ should handle error for failed validation (2ms)
----------|----------|----------|----------|----------|-------------------|
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s |
----------|----------|----------|----------|----------|-------------------|
All files | 100 | 100 | 100 | 100 | |
ctrl.js | 100 | 100 | 100 | 100 | |
----------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests: 2 passed, 2 total
Snapshots: 0 total
Time: 19.59s