I want to abstract the client API responses from the tests and I'm trying to come up with a helper for that, for example:
class MockedClientApi {
constructor() {
this.nock = nock('https://client.domain.com');
}
getCountryInfo(country) {
const endpoint = `/api/info/country/${country}`;
return this.nock(endpoint).reply(200, responses.getCountryInfo);
}
getUserInfo(userId) {
const endpoint = `/api/info/user/${userId}`;
return this.nock(endpoint).reply(200, responses.getUserInfo);
}
}
and then in tests, I can write something like:
let mockedRequests;
before('mock calls', () => {
mockedRequests = [
global.clientApi.getCountryInfo('GB'),
global.clientApi.getUserInfo('ABC')
];
});
and of course, this is not like the chaining that nock uses:
mockedRequests = nock('https://client.domain.com')
.get(`/api/info/country/${country}`)
.reply(200, responses.getCountryInfo)
.get(`/api/info/user/${userId}`)
.reply(200, responses.getUserInfo)
as later I do:
describe('when client API is called', () => {
it('should call all mocked endpoints', () => {
expect(mockedRequests.pendingMocks()).to.deep.equal([]);
});
});
How can one do chaining from dynamic calls/single calls?
I even tried to come up with ideas that didn't work, like:
mockedRequests = nock([
global.clientApi.getCountryInfo('GB'),
global.clientApi.getUserInfo('ABC')
]);
It looks like you are initializing nock multiple times, ending up with multiple/different instances or mutating the original one.
In each class function where you add a mocked request, you should call the instance of nock's "method" function (get
, post
, etc.) to add each endpoint you want to mock. Then you could add a function to get the full instance of nock or just create helper functions for each assertion you need, like getPendingMocks()
.
const { expect } = require('chai');
const nock = require('nock');
class MockedClientApi {
constructor() {
this.mockedApi = nock('https://google.com')
}
getCountryInfo(country) {
const endpoint = `/api/info/country/${country}`;
return this.mockedApi.get(endpoint).reply(200, responses.getCountryInfo); // return might be unnecessary
}
getUserInfo(userId) {
const endpoint = `/api/info/user/${userId}`;
return this.mockedApi.get(endpoint).reply(200, responses.getUserInfo);
}
getPendingMocks() {
return this.mockedApi.pendingMocks();
}
}
describe('make tests', () => {
let mockedClientApi;
before('get mock', () => {
mockedClientApi = new MockedClientApi();
mockedClientApi.getCountryInfo();
mockedClientApi.getUserInfo();
});
it('should call google', () => {
expect(mockedClientApi.getPendingMocks()).to.deep.equal([]);
});
});
In the end you should also consider adding an after
function to clear nock.