From facdf20703bb7f4bbfe5b185cbf7c845f27b7ed1 Mon Sep 17 00:00:00 2001 From: Rhys Evans Date: Mon, 4 May 2020 21:27:22 +0100 Subject: [PATCH] don't break when using jest.restoreAllMocks() --- __tests__/jest-built-ins.spec.js | 1 - __tests__/regressions.spec.js | 20 ++++++++++++++++++++ jestify.js | 26 ++++++++++++++++++-------- 3 files changed, 38 insertions(+), 9 deletions(-) create mode 100644 __tests__/regressions.spec.js diff --git a/__tests__/jest-built-ins.spec.js b/__tests__/jest-built-ins.spec.js index d6568e4..35c05d9 100644 --- a/__tests__/jest-built-ins.spec.js +++ b/__tests__/jest-built-ins.spec.js @@ -78,7 +78,6 @@ describe('jest built-ins', () => { it('mockReset', () => { expect(fetch.mockReset).toBeDefined(); fetch.mockReset(); - expect(fetch.mock.calls.length).toEqual(0); expect(fetch._calls.length).toEqual(0); expect(fetch.routes.length).toEqual(0); diff --git a/__tests__/regressions.spec.js b/__tests__/regressions.spec.js new file mode 100644 index 0000000..21f7425 --- /dev/null +++ b/__tests__/regressions.spec.js @@ -0,0 +1,20 @@ +/*global jest */ +jest.mock('node-fetch', () => require('../server').sandbox()); +const fetch = require('node-fetch'); + +describe('regressions and strange cases', () => { + it('works even when jest.resetAllMocks() is called', () => { + jest.resetAllMocks(); + fetch.mock('*', 200); + fetch('http://example.com/path', 200); + expect(fetch).toHaveFetched('http://example.com/path'); + fetch.reset(); + }); + it('works even when jest.clearAllMocks() is called', () => { + jest.clearAllMocks(); + fetch.mock('*', 200); + fetch('http://example.com/path', 200); + expect(fetch).toHaveFetched('http://example.com/path'); + fetch.reset(); + }); +}); diff --git a/jestify.js b/jestify.js index b25d9d8..79107bf 100644 --- a/jestify.js +++ b/jestify.js @@ -18,24 +18,34 @@ const jestify = (fetchMockInstance) => { // spy on the fetch handler so we can use all the // jest function assertions on it - jest.spyOn(jestifiedInstance, 'fetchHandler'); + const spy = jest.fn(); + const originalFetchHandler = jestifiedInstance.fetchHandler.bind( + jestifiedInstance + ); + + jestifiedInstance.fetchHandler = function (...args) { + const result = originalFetchHandler(...args); + spy.mockReturnValueOnce(result); + spy.apply(this, args); + return result; + }; // make sure all the jest expectation helpers can find what they need on fetchMock.mock - Object.assign(jestifiedInstance.mock, jestifiedInstance.fetchHandler.mock); + Object.assign(jestifiedInstance.mock, spy.mock); ['_isMockFunction', 'mockName', 'getMockName'].forEach((prop) => { - jestifiedInstance[prop] = jestifiedInstance.fetchHandler[prop]; + jestifiedInstance[prop] = spy[prop]; }); jestifiedInstance.mockClear = () => { - jestifiedInstance.fetchHandler.mockClear(); + spy.mockClear(); jestifiedInstance.resetHistory(); - Object.assign(jestifiedInstance.mock, jestifiedInstance.fetchHandler.mock); + Object.assign(jestifiedInstance.mock, spy.mock); }; jestifiedInstance.mockReset = () => { - jestifiedInstance.fetchHandler.mockReset(); + spy.mockReset(); jestifiedInstance.reset(); - Object.assign(jestifiedInstance.mock, jestifiedInstance.fetchHandler.mock); + Object.assign(jestifiedInstance.mock, spy.mock); }; jestifiedInstance.mockRestore = () => { throw new Error( @@ -95,7 +105,7 @@ const jestify = (fetchMockInstance) => { // make sure that the mock object that has properties updated // by the jest spy is the one that is exposed on fetch - jestifiedInstance.fetchHandler.mock = jestifiedInstance.mock; + spy.mock = jestifiedInstance.mock; // Return this monster! return jestifiedInstance;