Bài viết được sự cho phép của tác giả Lê Chí Dũng
Trước khi tham khảo thông tin bài viết này, bạn cần biết về Integration test là gì? Và Nock là một giải pháp tốt trong việc mocking các request đến các APIs khi làm với NodeJS để trả ra expected bạn mong muốn.
I. Tại sao phải dùng Nock?
Khi chạy Integration test chúng ta khó có thể Injection vào function để mock như Unit test được. Vì thế việc gọi các APIs và trả ra dữ liệu mong muốn với phương thức Injection vào function thì khá khó khăn.
Việc mock vào HTTP request để các APIs trả ra dữ liệu thì khả quan hơn!
Ví dụ: Itegration có function gọi tới API của Amazon mà mock nó trả ra dữ liệu mình muốn.
Có rất nhiều package tương tự Nock như Pact, Chai, Sinon nhưng việc sử dụng thì mình thấy Nock hoạt động dễ dàng và cách dùng rất dễ hiểu!
Repo: https://github.com/nock/nock
NPM: https://www.npmjs.com/package/nock
II. Nock hoạt động như thế nào?
Nock hoạt động bằng cách ghi đè hàm http.request của Node. Ngoài ra, nó cũng ghi đè lên http.ClientRequest để đề cập đến các module sử dụng trực tiếp.
III. Cách sử dụng Nock để mock HTTP request hiệu quả.
Mình tham khảo hoàn toàn từ tài liệu của Nock cung cấp và kết hợp với Chai để tiến code Integration test.
Nock document: https://github.com/nock/nock#usage
Cách mà mình sử dụng Nock cho việc Integration test.
https://github.com/lechidung/test-source-sample-for-nodejs
'use strict';
const request = require('request');
const chai = require('chai');
const chaiHttp = require('chai-http');
const nock = require('nock');
const server = require('../../../src/app');
const {api} = require('../../../src/configs');
const dataProvider = require('./dataProvider/books');
const testCase = require('./testCase/books');
const RealDate = Date;
function mockDate (isoDate) {
global.Date = class extends RealDate {
constructor () {
return new RealDate(isoDate)
}
}
}
describe('books Detail API Success', () => {
before(() => {
chai.use(chaiHttp);
});
beforeEach(() => {
global.Date = RealDate;
mockDate('2018-07-12T12:00:00z');
// Mock CMS API get books Detail
nock(api['BOOK_DETAIL'].host)
.get(api['BOOK_DETAIL'].path)
.query({
url_key: 'book_code'
})
.reply(200, dataProvider.book_info);
// Mock get IAM Data API
nock(api['IAM'].host, {
reqheaders: {
'App-Auth': 'PemToken'
}
})
.get(api['IAM'].path)
.query({
fields: 'login, reg, prem, iden'
})
.reply(200, dataProvider.IAMResult);
// Mock Target User API
let iamDataStr = JSON.stringify(dataProvider.IAMData);
let iamDataBase64 = Buffer.from(iamDataStr).toString("base64");
nock(api['TARGET_USER'].host)
.get(api['TARGET_USER'].path)
.query({
cp_id: dataProvider.book_info.book_id,
date: 20180712190000,
iam_data: iamDataBase64
})
.reply(200, dataProvider.targetUser);
});
afterEach(() => {
global.Date = RealDate;
});
testCase.forEach(v => {
it(v.caseName, done => {
// When
chai.request(server)
.get(v.path)
.set(v.headers)
.query(v.queryParameters)
.end((err, res) => {
// Then
expect(res).to.have.status(v.expected.status);
expect(res.body).to.deep.equal(v.expected.body);
done();
});
});
});
});
Có thể bạn quan tâm: