I am trying to use nock to intercept/mock some HTTP traffic in my application for testing purposes. Our app authenticates to another one of our sites, and I need nock to imitate an HTTP 200 (with JSON data) and an HTTP 401 (with no data) to test behaviors when the user is or isn't logged in there (respectively).
I have two tests which both work correctly when run alone, but if I run the entire test suite, one of them always fails. I realize that nock is shared state because it modifies how node.js itself handles network traffic and I assume that's the cause of the race condition, but I can't be the only person who's ever used two different nock interceptors for the same request in two different tests, so I know I'm missing something.
Can anyone help me figure out why these tests are stepping on each other?
My question is related to How to retest same URL using Mocha and Nock? but I did the things suggested there and they didn't help.
My test files (which, again, both work fine if called individually, but fail when run as part of the same test pass) look like this:
import { expect } from 'chai';
import nock from 'nock';
import * as actionTypes from '../../src/constants/action-types';
import * as panoptes from '../../src/services/panoptes';
import { user } from '../modules/users/test-data';
const stagingHost = 'https://my-staging-server.org';
describe('Panoptes', () => {
afterEach(function (done) {
nock.cleanAll();
nock.disableNetConnect();
done();
});
beforeEach(function (done) {
nock.cleanAll();
nock.disableNetConnect();
done();
});
describe('with a valid user', function (done) {
let lastAction = null;
const scope = nock(stagingHost)
.get(/^\/oauth\/authorize/)
.reply(302, '', {
'location': 'https://localhost:3000',
'Strict-Transport-Security': 'max-age=31536000; includeSubDomains',
'X-Frame-Options': 'SAMEORIGIN',
'X-XSS-Protection': '1; mode=block',
});
scope
.get(/^\/api\/me/)
.reply(200, {
users: [user],
});
panoptes.checkLoginUser((action) => { lastAction = action; }).then(() => {
nock.removeInterceptor(scope);
done();
});
it('should know when somebody is logged in', function () {
expect(lastAction).to.not.be.null;
expect(lastAction.type).to.equal(actionTypes.SET_LOGIN_USER);
expect(lastAction.user).to.not.be.null;
expect(lastAction.user.id).to.equal(user.id);
expect(lastAction.user.login).to.equal(user.login);
});
});
});
and
import { expect } from 'chai';
import nock from 'nock';
import * as actionTypes from '../../src/constants/action-types';
import * as panoptes from '../../src/services/panoptes';
const stagingHost = 'https://my-staging-server.org';
describe('Panoptes', () => {
afterEach(function (done) {
nock.cleanAll();
nock.disableNetConnect();
done();
});
beforeEach(function (done) {
nock.cleanAll();
nock.disableNetConnect();
done();
});
describe('with no user', function (done) {
let lastAction = null;
const scope = nock(stagingHost)
.get(/^\/oauth\/authorize/)
.reply(302, '', {
'Cache-Control': 'no-cache',
'location': 'https://my-staging-server.org/users/sign_in',
'Strict-Transport-Security': 'max-age=31536000; includeSubDomains',
'X-Frame-Options': 'SAMEORIGIN',
'X-XSS-Protection': '1; mode=block',
});
scope
.get(/^\/api\/me/)
.reply(401);
panoptes.checkLoginUser((action) => { lastAction = action; }).then(() => {
nock.removeInterceptor(scope);
done();
});
it('should know that nobody is logged in', function () {
expect(lastAction).to.not.be.null;
expect(lastAction.type).to.equal(actionTypes.SET_LOGIN_USER);
expect(lastAction.user).to.be.null;
});
});
});