Skip to content

"pendingMocks" includes duplicates of the same mock and "removeInterceptor" does nothing #600

@cjthompson

Description

@cjthompson

Version 8.0.0

Here's some sample code that demonstrates the issue:

'use strict';

// Sample

const nock = require('nock');
const scope = nock('http://test');

function setup() {
  scope.get('/').reply(200);
  console.log('setup1-scope', scope.pendingMocks()); // [ 'GET http://test:80/' ]
  console.log('setup1-nock', nock.pendingMocks()); // [ 'GET http://test:80/' ]

  scope.get('/1').reply(200);
  console.log('setup2-scope', scope.pendingMocks()); // [ 'GET http://test:80/', 'GET http://test:80/1' ]
  console.log('setup2-nock', nock.pendingMocks()); // [ 'GET http://test:80/', 'GET http://test:80/1', 'GET http://test:80/', 'GET http://test:80/1' ]

  scope.get('/2').reply(200);
  console.log('setup3-scope', scope.pendingMocks()); // [ 'GET http://test:80/', 'GET http://test:80/1', 'GET http://test:80/2' ]
  console.log('setup3-nock', nock.pendingMocks());
  // [ 'GET http://test:80/',
  // 'GET http://test:80/1',
  // 'GET http://test:80/2',
  // 'GET http://test:80/',
  // 'GET http://test:80/1',
  // 'GET http://test:80/2',
  // 'GET http://test:80/',
  // 'GET http://test:80/1',
  // 'GET http://test:80/2'
  // ]
}

function example1() {
  const req = require('http')
    .request('http://test', (res) => {
      console.log('removeInterceptor');
      nock.removeInterceptor(scope.interceptors[0]);
      console.log('example1-scope', scope.pendingMocks());
      // [ 'GET http://test:80/1', 'GET http://test:80/2' ]
      console.log('example1-nock', nock.pendingMocks());
      // [ 'GET http://test:80/1',
      // 'GET http://test:80/2',
      // 'GET http://test:80/1',
      // 'GET http://test:80/2',
      // ]
      console.log('removeInterceptor');
      nock.removeInterceptor(scope.interceptors[0]);
      console.log('example1-scope2', scope.pendingMocks());
      // [ 'GET http://test:80/1', 'GET http://test:80/2' ]
      console.log('example1-nock2', nock.pendingMocks());
      // [ 'GET http://test:80/1',
      // 'GET http://test:80/2',
      // 'GET http://test:80/1',
      // 'GET http://test:80/2',
      // ]
      console.log('request');
      const req2 = require('http')
        .request('http://test/1', (res) => {
          console.log('example1-scope3', scope.pendingMocks());
          console.log('example1-nock3', nock.pendingMocks());
          scope.done(); // shouldn't throw an exception
        });
      req2.end();
    });
  req.end();
}

function example2() {
  console.log('removeInterceptor');
  nock.removeInterceptor({ hostname: 'test', path: '/' });
  console.log('example2-scope1', scope.pendingMocks());
  console.log('example2-nock1', nock.pendingMocks());

  console.log('removeInterceptor');
  nock.removeInterceptor({ hostname: 'test', path: '/1' });
  console.log('example2-scope2', scope.pendingMocks());
  console.log('example2-nock2', nock.pendingMocks());

  console.log('removeInterceptor');
  nock.removeInterceptor({ hostname: 'test', path: '/2' });
  console.log('example2-scope3', scope.pendingMocks());
  console.log('example2-nock3', nock.pendingMocks());
  scope.done(); // shouldn't throw an exception
}

function example3() {
  setImmediate(() => {
    console.log('removeInterceptors');
    nock.removeInterceptor({ hostname: 'test', path: '/' });
    nock.removeInterceptor({ hostname: 'test', path: '/1' });
    nock.removeInterceptor({ hostname: 'test', path: '/2' });
    setImmediate(() => {
      console.log('example3-scope', scope.pendingMocks());
      console.log('example3-nock', nock.pendingMocks());
      scope.done();
    });
  });
}

try {
  setup();
  example2();
} catch (e) {
  console.log(e);
  console.log('----------------\n\n');
}

try {
  setup();
  example3();
} catch (e) {
  console.log(e);
  console.log('----------------\n\n');
}

setup();
example1();

If you run that code, you'll find:

  • nock.pendingMocks() returns number of mocks per scope squared. For example, if you use scope.get().reply() 3 times, you'll get 9 entries.
  • nock.removeInterceptor doesn't work. If you call scope.get().reply() twice, pendingMocks will show 4 entries. After calling removeInterceptor, there will only be 2 entries, so something gets removed. However, scope.done() will still throw an exception that the mock is not satisfied

When logging out the value of allInterceptors, there appears to be a lot of duplication of mocks and a lot of circular references.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions