My Controller => below controller is using reqpoertService.getFiles method and that method itself using a external APIs to call the data.
function getFiles(req, res) {
reportService.getFiles({
fromDate: req.query.fromdate,
endDate: req.query.enddate,
fileTypes: req.query.filetypes || [],
fileStatus: req.query.filestatus || []
})
.then(data => {
logger.info('-> reportService.getFiles :: Successfully fetched data',
resolveLogger({ statusCode: res.statusCode })
);
res.send(data);
})
.catch(err => {
logger.error('<- OOPS :: reportService.getFiles fail to fetch data');
res.status(statusCodes.INTERNAL_SERVER_ERROR).send({});
logger.error('<- ERROR', resolveLogger({
statusCode: res.statusCode,
errMessage: err.message,
errorStack: err
}));
});
}
Reporter Service
function getFiles() {
return new Promise((resolve, reject) => {
requestPromise(options)
.then(data => {
var duration = new Date - start;
logger.info(resolveLogger({
duration: duration + 'ms',
reqUrl: options.url,
bodyLengh: data && data.length
}));
logger.info('<= Request complete successfully.');
var resData = JSON.parse(data);
resolve(resData);
})
.catch(error => {
logger.error('=> Request failed for URL:', options.url);
reject(error);
});
});
}
My Unit Test Approach to test above controller
it('METHOD: getFiles -> should response 500 without data', done => {
nock('http://localhost:1708/fakeapi')
.get('/files')
.reply(statusCodes.INTERNAL_SERVER_ERROR);
const res = buildResponse();
const req = httpMocks.createRequest({
method: 'GET',
url: '/api/submitted-data/1/files'
});
res.on('end', function () {
var data = res._getData();
expect(data).toEqual({});
expect(statusCodes.INTERNAL_SERVER_ERROR).toBe(res.statusCode);
done();
nock.cleanAll();
});
reporterController.getFiles(req, res);
});
Can someone suggest me the approach I am following is acceptable or is there any better approach to do the unit test. As I am beginner to do the unit testing.
I think your approach is on the right path. Your tests should be decoupled as much from the implementation as much as possible. So your test code shouldn't really know how you've implemented your code. It just cares that when you hit your endpoints, the outcome is as expected. You want to mock the external parts of your code, i.e. the code that won't execute when you run your test such as external APIs. You can mock certain responses that the external APIs so you can write tests to cover those types of scenarios and then handle them as you want.
This article from ThoughtWorks is quite helpful in explaining this approach to testing: https://www.thoughtworks.com/insights/blog/mockists-are-dead-long-live-classicists
I'd also suggest watching this video title Ian Cooper: TDD where did it all go wrong: https://vimeo.com/68375232
I appreciate my suggestion is a little high level so in short I think your test should look like:
You can then have different tests checking different responses that the external apis return.
I have one criticism of you unit test, and it is that you aren't using beforeAll/each to actually setup your test.
What I mean by this is:
Appart from that it looks good.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With