Hướng dẫn sử dụng Nock để mock request APIs cho việc run Integration test

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.

  10+ tools và extensions tuyệt vời cho GraphQL APIs
  3 bước tối ưu hiệu năng React App bằng các API mới của React

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();
            });
        });
    });
});
Bài viết gốc được đăng tải tại lcdung.top
Có thể bạn quan tâm:
Xem thêm Việc làm Developer hấp dẫn trên TopDev