I'm trying to test a rest api which calls an external service.
const express = require('express');
const app = express();
const router = express.Router();
const redirectUrl = require('../utils/redirection')
let baseUrl = 'myUrl';
let externalUrl = 'externalUrl';
router.get('/redirect', async (req, res) => {
const { productName } = req.query;
baseUrl = baseUrl + '/' + productName;
externalUrl = externalUrl + '/' + productName;
await redirectUrl(res)(timeOut, externalUrl, baseUrl)
})
app.use(router);
app.listen(3000);
edirectUrl = res => (timeOut, url, redirectUrl) => {
return new Promise((resolve, reject) => {
let cleared = false;
const timer = setTimeout(() => {
cleared = true;
return resolve(res.redirect(302, redirectUrl));
}, timeout);
return fetch(url)
.then(
response => {
if (!cleared) {
clearTimeout(timer);
const {location} = response.headers;
return resolve(res.redirect(302, location));
}
return null;
})
.catch(err => {
if (!cleared) {
clearTimeout(timer);
return reject(err);
}
});
});
}
const requrest = require('request');
const chai = require('chai');
const server = require('../server/server');
const { expect } = chai;
describe('My test', () => {
it('should redirects to the suitable page', () => {
nock('url/to/external/service')
.get('/${productName}')
.reply(302, {
headers: {
location: 'this the page location'
}})
const { status, headers } = request(app).get('/redirect')
expect(status).to.equal(302);
expect(headers.location).to.not.equal(0);
})
})
When I execute the test, the request
launches the API call. Then the redirectUrl
was called inside. But nock
does not intercept the request and the server call the external api. Does nock could intercept a depth HTTP request? or I missed something in my code? Does any suggestion please to resolve this problem?
Without a running example it's hard to tell what is going wrong. But I can tell there's a few things you can change here (I was also struggling with Nock today).
First, since you're dealing with redirects, take a look at this comment. This worked for me: https://github.com/nock/nock/issues/147#issuecomment-71433752
Second, pay attention: the syntax to specify headers is wrong, this is the correct one:
nock('url/to/external/service')
.get('/${productName}')
.reply(302, 'whatever you want', {
location: 'http://the.other.page.location'
})
Third: split your server.js file into two: server.js and app.js.
app.js
const app = express()
...
module.exports = app
server.js
const app = require('./path/to/app.js')
...
app.listen(3000)
This way you can import your app.js into your test suite without the listen part, which will avoid problems with network ports when new tests are run.
Let me know if this helped...