Partially mock React module with JestLoop inside React JSXProgrammatically navigate using react routerHow to test a React Native component that imports a custom native module with Jest?babel-jest doesn't handle ES6 within modulesHow to “mock” navigator.geolocation in a React Jest TestJest mock of gRPC fails with manual definitionMock import/module with Jest in React applicationJest: How to correctly mock a node module?jest module executed even when mockedjest.mock() not mocking module in Babel 7 and React-Native 0.56

Group Integers by Originality

Are there any important biographies of nobodies?

How to hide an urban landmark?

Why are trash cans referred to as "zafacón" in Puerto Rico?

Is separation provided in class F airspace?

How is John Wick 3 a 15 certificate?

How did old MS-DOS games utilize various graphic cards?

CROSS APPLY produces outer join

What setting controls moving the cursor on the command line?

What is the maximum number of net attacks that one can make in a round?

Bent Peugeot Carbolite 103 Frame

What makes Ada the language of choice for the ISS's safety-critical systems?

Does a scale have more than seven chords?

Tabular make widths equal

Longest bridge/tunnel that can be cycled over/through?

Thread Pool C++ Implementation

Did Milano or Benatar approve or comment on their namesake MCU ships?

How come the nude protesters were not arrested?

How to handle self harm scars on the arm in work environment?

Is it expected that a reader will skip parts of what you write?

Check if three arrays contains the same element

I have a problem assistant manager, but I can't fire him

Russian word for a male zebra

Why didn't Voldemort recognize that Dumbledore was affected by his curse?



Partially mock React module with Jest


Loop inside React JSXProgrammatically navigate using react routerHow to test a React Native component that imports a custom native module with Jest?babel-jest doesn't handle ES6 within modulesHow to “mock” navigator.geolocation in a React Jest TestJest mock of gRPC fails with manual definitionMock import/module with Jest in React applicationJest: How to correctly mock a node module?jest module executed even when mockedjest.mock() not mocking module in Babel 7 and React-Native 0.56






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty height:90px;width:728px;box-sizing:border-box;








4















I'm trying to mock only one function in imported React module, keep the rest of the module unmocked and do this at top level for all tests.



I'm using fresh create-react-app project with a single test to observe the problem.



Steps to reproduce:



  • create-react-app test

  • use provided src/App.test.js as the only test file

  • npm run test

App.test.js



jest.mock('react', () => 
jest.dontMock('react');

const React = require('react');
const lazy = jest.fn();

return
...React,
lazy
;
);

import * as React from 'react';
const React2 = require('react');

it('should partially mock React module', async () =>
expect(jest.isMockFunction(React.lazy)).toBe(true); // passes
expect(jest.isMockFunction(React2.lazy)).toBe(true); // fails
expect(jest.isMockFunction(require('react').lazy)).toBe(true); // fails
expect(jest.isMockFunction((await import('react')).lazy)).toBe(true); // fails
);


The problem here seems to be jest.dontMock as it prevents require and dynamic import from being mocked, but it remains unclear why it was possible to mock static import this way, as it uses require any way. Here's transpiled file:



"use strict";

jest.mock('react', () =>
jest.dontMock('react');

const React = require('react');

const lazy = jest.fn();
return (0, _objectSpread2.default)(, React,
lazy
);
);

var _interopRequireWildcard3 = require("...\node_modules\@babel\runtime/helpers/interopRequireWildcard");

var _interopRequireDefault = require("...\node_modules\@babel\runtime/helpers/interopRequireDefault");

var _interopRequireWildcard2 = _interopRequireDefault(require("...\node_modules\@babel\runtime/helpers/interopRequireWildcard"));

var _objectSpread2 = _interopRequireDefault(require("...\node_modules\@babel\runtime/helpers/objectSpread"));

var React = _interopRequireWildcard3(require("react"));

const React2 = require('react');
...


This may have something to do with create-react-app Jest+Babel setup because I was unable to make jest.dontMock work incorrectly with vanilla Jest and require.



Why is static React import mocked but React2 and the rest aren't? What exactly is going on inside?



How can jest.dontMock current behaviour be fixed to partially mock a module at top level?










share|improve this question
























  • I think require.requireActual should do the trick as mentioned in this issue. Also jest.dontMock('react') is not needed with this. I don't know why dontMock is behaving differently for import vs require - it should prevent mocking in both cases.

    – AWolf
    Mar 24 at 20:37






  • 1





    @AWolf I knew about requireActual but totally forgot about it and somehow overlooked it in the issue you linked. Indeed, that's the solution, thank you. Consider providing this fix as an answer if you wish.

    – Estus Flask
    Mar 24 at 22:24

















4















I'm trying to mock only one function in imported React module, keep the rest of the module unmocked and do this at top level for all tests.



I'm using fresh create-react-app project with a single test to observe the problem.



Steps to reproduce:



  • create-react-app test

  • use provided src/App.test.js as the only test file

  • npm run test

App.test.js



jest.mock('react', () => 
jest.dontMock('react');

const React = require('react');
const lazy = jest.fn();

return
...React,
lazy
;
);

import * as React from 'react';
const React2 = require('react');

it('should partially mock React module', async () =>
expect(jest.isMockFunction(React.lazy)).toBe(true); // passes
expect(jest.isMockFunction(React2.lazy)).toBe(true); // fails
expect(jest.isMockFunction(require('react').lazy)).toBe(true); // fails
expect(jest.isMockFunction((await import('react')).lazy)).toBe(true); // fails
);


The problem here seems to be jest.dontMock as it prevents require and dynamic import from being mocked, but it remains unclear why it was possible to mock static import this way, as it uses require any way. Here's transpiled file:



"use strict";

jest.mock('react', () =>
jest.dontMock('react');

const React = require('react');

const lazy = jest.fn();
return (0, _objectSpread2.default)(, React,
lazy
);
);

var _interopRequireWildcard3 = require("...\node_modules\@babel\runtime/helpers/interopRequireWildcard");

var _interopRequireDefault = require("...\node_modules\@babel\runtime/helpers/interopRequireDefault");

var _interopRequireWildcard2 = _interopRequireDefault(require("...\node_modules\@babel\runtime/helpers/interopRequireWildcard"));

var _objectSpread2 = _interopRequireDefault(require("...\node_modules\@babel\runtime/helpers/objectSpread"));

var React = _interopRequireWildcard3(require("react"));

const React2 = require('react');
...


This may have something to do with create-react-app Jest+Babel setup because I was unable to make jest.dontMock work incorrectly with vanilla Jest and require.



Why is static React import mocked but React2 and the rest aren't? What exactly is going on inside?



How can jest.dontMock current behaviour be fixed to partially mock a module at top level?










share|improve this question
























  • I think require.requireActual should do the trick as mentioned in this issue. Also jest.dontMock('react') is not needed with this. I don't know why dontMock is behaving differently for import vs require - it should prevent mocking in both cases.

    – AWolf
    Mar 24 at 20:37






  • 1





    @AWolf I knew about requireActual but totally forgot about it and somehow overlooked it in the issue you linked. Indeed, that's the solution, thank you. Consider providing this fix as an answer if you wish.

    – Estus Flask
    Mar 24 at 22:24













4












4








4








I'm trying to mock only one function in imported React module, keep the rest of the module unmocked and do this at top level for all tests.



I'm using fresh create-react-app project with a single test to observe the problem.



Steps to reproduce:



  • create-react-app test

  • use provided src/App.test.js as the only test file

  • npm run test

App.test.js



jest.mock('react', () => 
jest.dontMock('react');

const React = require('react');
const lazy = jest.fn();

return
...React,
lazy
;
);

import * as React from 'react';
const React2 = require('react');

it('should partially mock React module', async () =>
expect(jest.isMockFunction(React.lazy)).toBe(true); // passes
expect(jest.isMockFunction(React2.lazy)).toBe(true); // fails
expect(jest.isMockFunction(require('react').lazy)).toBe(true); // fails
expect(jest.isMockFunction((await import('react')).lazy)).toBe(true); // fails
);


The problem here seems to be jest.dontMock as it prevents require and dynamic import from being mocked, but it remains unclear why it was possible to mock static import this way, as it uses require any way. Here's transpiled file:



"use strict";

jest.mock('react', () =>
jest.dontMock('react');

const React = require('react');

const lazy = jest.fn();
return (0, _objectSpread2.default)(, React,
lazy
);
);

var _interopRequireWildcard3 = require("...\node_modules\@babel\runtime/helpers/interopRequireWildcard");

var _interopRequireDefault = require("...\node_modules\@babel\runtime/helpers/interopRequireDefault");

var _interopRequireWildcard2 = _interopRequireDefault(require("...\node_modules\@babel\runtime/helpers/interopRequireWildcard"));

var _objectSpread2 = _interopRequireDefault(require("...\node_modules\@babel\runtime/helpers/objectSpread"));

var React = _interopRequireWildcard3(require("react"));

const React2 = require('react');
...


This may have something to do with create-react-app Jest+Babel setup because I was unable to make jest.dontMock work incorrectly with vanilla Jest and require.



Why is static React import mocked but React2 and the rest aren't? What exactly is going on inside?



How can jest.dontMock current behaviour be fixed to partially mock a module at top level?










share|improve this question
















I'm trying to mock only one function in imported React module, keep the rest of the module unmocked and do this at top level for all tests.



I'm using fresh create-react-app project with a single test to observe the problem.



Steps to reproduce:



  • create-react-app test

  • use provided src/App.test.js as the only test file

  • npm run test

App.test.js



jest.mock('react', () => 
jest.dontMock('react');

const React = require('react');
const lazy = jest.fn();

return
...React,
lazy
;
);

import * as React from 'react';
const React2 = require('react');

it('should partially mock React module', async () =>
expect(jest.isMockFunction(React.lazy)).toBe(true); // passes
expect(jest.isMockFunction(React2.lazy)).toBe(true); // fails
expect(jest.isMockFunction(require('react').lazy)).toBe(true); // fails
expect(jest.isMockFunction((await import('react')).lazy)).toBe(true); // fails
);


The problem here seems to be jest.dontMock as it prevents require and dynamic import from being mocked, but it remains unclear why it was possible to mock static import this way, as it uses require any way. Here's transpiled file:



"use strict";

jest.mock('react', () =>
jest.dontMock('react');

const React = require('react');

const lazy = jest.fn();
return (0, _objectSpread2.default)(, React,
lazy
);
);

var _interopRequireWildcard3 = require("...\node_modules\@babel\runtime/helpers/interopRequireWildcard");

var _interopRequireDefault = require("...\node_modules\@babel\runtime/helpers/interopRequireDefault");

var _interopRequireWildcard2 = _interopRequireDefault(require("...\node_modules\@babel\runtime/helpers/interopRequireWildcard"));

var _objectSpread2 = _interopRequireDefault(require("...\node_modules\@babel\runtime/helpers/objectSpread"));

var React = _interopRequireWildcard3(require("react"));

const React2 = require('react');
...


This may have something to do with create-react-app Jest+Babel setup because I was unable to make jest.dontMock work incorrectly with vanilla Jest and require.



Why is static React import mocked but React2 and the rest aren't? What exactly is going on inside?



How can jest.dontMock current behaviour be fixed to partially mock a module at top level?







javascript reactjs jestjs create-react-app babel-jest






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Mar 24 at 20:28







Estus Flask

















asked Mar 24 at 18:29









Estus FlaskEstus Flask

83.4k24129251




83.4k24129251












  • I think require.requireActual should do the trick as mentioned in this issue. Also jest.dontMock('react') is not needed with this. I don't know why dontMock is behaving differently for import vs require - it should prevent mocking in both cases.

    – AWolf
    Mar 24 at 20:37






  • 1





    @AWolf I knew about requireActual but totally forgot about it and somehow overlooked it in the issue you linked. Indeed, that's the solution, thank you. Consider providing this fix as an answer if you wish.

    – Estus Flask
    Mar 24 at 22:24

















  • I think require.requireActual should do the trick as mentioned in this issue. Also jest.dontMock('react') is not needed with this. I don't know why dontMock is behaving differently for import vs require - it should prevent mocking in both cases.

    – AWolf
    Mar 24 at 20:37






  • 1





    @AWolf I knew about requireActual but totally forgot about it and somehow overlooked it in the issue you linked. Indeed, that's the solution, thank you. Consider providing this fix as an answer if you wish.

    – Estus Flask
    Mar 24 at 22:24
















I think require.requireActual should do the trick as mentioned in this issue. Also jest.dontMock('react') is not needed with this. I don't know why dontMock is behaving differently for import vs require - it should prevent mocking in both cases.

– AWolf
Mar 24 at 20:37





I think require.requireActual should do the trick as mentioned in this issue. Also jest.dontMock('react') is not needed with this. I don't know why dontMock is behaving differently for import vs require - it should prevent mocking in both cases.

– AWolf
Mar 24 at 20:37




1




1





@AWolf I knew about requireActual but totally forgot about it and somehow overlooked it in the issue you linked. Indeed, that's the solution, thank you. Consider providing this fix as an answer if you wish.

– Estus Flask
Mar 24 at 22:24





@AWolf I knew about requireActual but totally forgot about it and somehow overlooked it in the issue you linked. Indeed, that's the solution, thank you. Consider providing this fix as an answer if you wish.

– Estus Flask
Mar 24 at 22:24












1 Answer
1






active

oldest

votes


















1














Default Imports:



A simple solution would be to mock React.lazy in the setupTest.js:



import React from 'react';
import configure from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
configure( adapter: new Adapter() );

jest.spyOn(React.lazy);


Any subsequent require/imports of react will be partially mocked for each test file.



Working example: https://github.com/mattcarlotta/react-lazy-mocked (I don't use the create-react-app, but jest can be set up the same way as I have it)



Installation:



  • git clone git@github.com:mattcarlotta/react-lazy-mocked.git

  • cd react-lazy-mocked

  • yarn install

  • yarn test


root/__tests__/root.test.js



import React from 'react';
import App from '../index.js';

const React2 = require('react');

describe('App', () =>
const wrapper = mount(<App />);

it('renders without errors', () =>
const homeComponent = wrapper.find('.app');
expect(homeComponent).toHaveLength(1);
);

it('should partially mock React module', async () =>
expect(jest.isMockFunction(await require('react').lazy)).toBe(true); // eslint-disable-line global-require
expect(jest.isMockFunction(React)).toBe(false);
expect(jest.isMockFunction(React.lazy)).toBe(true);
expect(jest.isMockFunction(React2)).toBe(false);
expect(jest.isMockFunction(React2.lazy)).toBe(true);
);

it('should no longer be partially mocked within the test file', () =>
React.lazy.mockRestore();
expect(jest.isMockFunction(React.lazy)).toBe(false);
);
);


pages/Home/__tests__/Home.test.js



import React from 'react';
import Home from '../index.js';

describe('Home', () =>
const wrapper = shallow(<Home />);

it('renders without errors', () =>
const homeComponent = wrapper.find('.app');
expect(homeComponent).toHaveLength(1);
);

it('should partially mock React module', async () =>
expect(jest.isMockFunction(React.lazy)).toBe(true);
);
);



Named Imports:



Working example: https://github.com/mattcarlotta/named-react-lazy-mocked



Installation:



  • git clone git@github.com:mattcarlotta/named-react-lazy-mocked.git

  • cd named-react-lazy-mocked

  • yarn install

  • yarn test

utils/__mocks__/react.js



jest.mock('react', () => (
...require.requireActual('react'),
lazy: jest.fn(),
));
module.exports = require.requireMock('react');


utils/setup/setupTest.js (optionally, you can add the mocked react file as a global jest function so you won't have to write import * as React from 'react' for every test):



import JSDOM from 'jsdom';
import configure from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
// import React from '../__mocks__/react';

configure( adapter: new Adapter() );

// global.React = React;


root/__tests__/root.test.js



import * as React from 'react';
import App from '../index.js';

const React2 = require('react');

describe('App', () =>
const wrapper = mount(<App />);

it('renders without errors', () =>
const homeComponent = wrapper.find('.app');
expect(homeComponent).toHaveLength(1);
);

it('should partially mock React module', async () =>
expect(jest.isMockFunction(await require('react').lazy)).toBe(true); // eslint-disable-line global-require
expect(jest.isMockFunction(React)).toBe(false);
expect(jest.isMockFunction(React.lazy)).toBe(true);
expect(jest.isMockFunction(React2)).toBe(false);
expect(jest.isMockFunction(React2.lazy)).toBe(true);
);
);





share|improve this answer

























  • Thanks for detailed answer. Sadly, this won't work for my case because the problem is to mock named imports. Things could be simpler for default import React from 'react' but I'm not using it. React imports are most often used as import React, lazy from 'react', where React default export is used only by Babel/TS to provide React.createElement for JSX transform.

    – Estus Flask
    Mar 24 at 22:19












  • Do you mean something like import * as React from 'react'; React.lazy = jest.fn()? This won't work due to how Babel's ES module interop works for *.

    – Estus Flask
    Mar 24 at 22:58











  • Figured it out for named exports. Updated the answer to include both.

    – Matt Carlotta
    Mar 24 at 23:49












  • Thanks, that's the way I'm doing this now.

    – Estus Flask
    Mar 25 at 9:44











Your Answer






StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");

StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);













draft saved

draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55327095%2fpartially-mock-react-module-with-jest%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









1














Default Imports:



A simple solution would be to mock React.lazy in the setupTest.js:



import React from 'react';
import configure from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
configure( adapter: new Adapter() );

jest.spyOn(React.lazy);


Any subsequent require/imports of react will be partially mocked for each test file.



Working example: https://github.com/mattcarlotta/react-lazy-mocked (I don't use the create-react-app, but jest can be set up the same way as I have it)



Installation:



  • git clone git@github.com:mattcarlotta/react-lazy-mocked.git

  • cd react-lazy-mocked

  • yarn install

  • yarn test


root/__tests__/root.test.js



import React from 'react';
import App from '../index.js';

const React2 = require('react');

describe('App', () =>
const wrapper = mount(<App />);

it('renders without errors', () =>
const homeComponent = wrapper.find('.app');
expect(homeComponent).toHaveLength(1);
);

it('should partially mock React module', async () =>
expect(jest.isMockFunction(await require('react').lazy)).toBe(true); // eslint-disable-line global-require
expect(jest.isMockFunction(React)).toBe(false);
expect(jest.isMockFunction(React.lazy)).toBe(true);
expect(jest.isMockFunction(React2)).toBe(false);
expect(jest.isMockFunction(React2.lazy)).toBe(true);
);

it('should no longer be partially mocked within the test file', () =>
React.lazy.mockRestore();
expect(jest.isMockFunction(React.lazy)).toBe(false);
);
);


pages/Home/__tests__/Home.test.js



import React from 'react';
import Home from '../index.js';

describe('Home', () =>
const wrapper = shallow(<Home />);

it('renders without errors', () =>
const homeComponent = wrapper.find('.app');
expect(homeComponent).toHaveLength(1);
);

it('should partially mock React module', async () =>
expect(jest.isMockFunction(React.lazy)).toBe(true);
);
);



Named Imports:



Working example: https://github.com/mattcarlotta/named-react-lazy-mocked



Installation:



  • git clone git@github.com:mattcarlotta/named-react-lazy-mocked.git

  • cd named-react-lazy-mocked

  • yarn install

  • yarn test

utils/__mocks__/react.js



jest.mock('react', () => (
...require.requireActual('react'),
lazy: jest.fn(),
));
module.exports = require.requireMock('react');


utils/setup/setupTest.js (optionally, you can add the mocked react file as a global jest function so you won't have to write import * as React from 'react' for every test):



import JSDOM from 'jsdom';
import configure from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
// import React from '../__mocks__/react';

configure( adapter: new Adapter() );

// global.React = React;


root/__tests__/root.test.js



import * as React from 'react';
import App from '../index.js';

const React2 = require('react');

describe('App', () =>
const wrapper = mount(<App />);

it('renders without errors', () =>
const homeComponent = wrapper.find('.app');
expect(homeComponent).toHaveLength(1);
);

it('should partially mock React module', async () =>
expect(jest.isMockFunction(await require('react').lazy)).toBe(true); // eslint-disable-line global-require
expect(jest.isMockFunction(React)).toBe(false);
expect(jest.isMockFunction(React.lazy)).toBe(true);
expect(jest.isMockFunction(React2)).toBe(false);
expect(jest.isMockFunction(React2.lazy)).toBe(true);
);
);





share|improve this answer

























  • Thanks for detailed answer. Sadly, this won't work for my case because the problem is to mock named imports. Things could be simpler for default import React from 'react' but I'm not using it. React imports are most often used as import React, lazy from 'react', where React default export is used only by Babel/TS to provide React.createElement for JSX transform.

    – Estus Flask
    Mar 24 at 22:19












  • Do you mean something like import * as React from 'react'; React.lazy = jest.fn()? This won't work due to how Babel's ES module interop works for *.

    – Estus Flask
    Mar 24 at 22:58











  • Figured it out for named exports. Updated the answer to include both.

    – Matt Carlotta
    Mar 24 at 23:49












  • Thanks, that's the way I'm doing this now.

    – Estus Flask
    Mar 25 at 9:44















1














Default Imports:



A simple solution would be to mock React.lazy in the setupTest.js:



import React from 'react';
import configure from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
configure( adapter: new Adapter() );

jest.spyOn(React.lazy);


Any subsequent require/imports of react will be partially mocked for each test file.



Working example: https://github.com/mattcarlotta/react-lazy-mocked (I don't use the create-react-app, but jest can be set up the same way as I have it)



Installation:



  • git clone git@github.com:mattcarlotta/react-lazy-mocked.git

  • cd react-lazy-mocked

  • yarn install

  • yarn test


root/__tests__/root.test.js



import React from 'react';
import App from '../index.js';

const React2 = require('react');

describe('App', () =>
const wrapper = mount(<App />);

it('renders without errors', () =>
const homeComponent = wrapper.find('.app');
expect(homeComponent).toHaveLength(1);
);

it('should partially mock React module', async () =>
expect(jest.isMockFunction(await require('react').lazy)).toBe(true); // eslint-disable-line global-require
expect(jest.isMockFunction(React)).toBe(false);
expect(jest.isMockFunction(React.lazy)).toBe(true);
expect(jest.isMockFunction(React2)).toBe(false);
expect(jest.isMockFunction(React2.lazy)).toBe(true);
);

it('should no longer be partially mocked within the test file', () =>
React.lazy.mockRestore();
expect(jest.isMockFunction(React.lazy)).toBe(false);
);
);


pages/Home/__tests__/Home.test.js



import React from 'react';
import Home from '../index.js';

describe('Home', () =>
const wrapper = shallow(<Home />);

it('renders without errors', () =>
const homeComponent = wrapper.find('.app');
expect(homeComponent).toHaveLength(1);
);

it('should partially mock React module', async () =>
expect(jest.isMockFunction(React.lazy)).toBe(true);
);
);



Named Imports:



Working example: https://github.com/mattcarlotta/named-react-lazy-mocked



Installation:



  • git clone git@github.com:mattcarlotta/named-react-lazy-mocked.git

  • cd named-react-lazy-mocked

  • yarn install

  • yarn test

utils/__mocks__/react.js



jest.mock('react', () => (
...require.requireActual('react'),
lazy: jest.fn(),
));
module.exports = require.requireMock('react');


utils/setup/setupTest.js (optionally, you can add the mocked react file as a global jest function so you won't have to write import * as React from 'react' for every test):



import JSDOM from 'jsdom';
import configure from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
// import React from '../__mocks__/react';

configure( adapter: new Adapter() );

// global.React = React;


root/__tests__/root.test.js



import * as React from 'react';
import App from '../index.js';

const React2 = require('react');

describe('App', () =>
const wrapper = mount(<App />);

it('renders without errors', () =>
const homeComponent = wrapper.find('.app');
expect(homeComponent).toHaveLength(1);
);

it('should partially mock React module', async () =>
expect(jest.isMockFunction(await require('react').lazy)).toBe(true); // eslint-disable-line global-require
expect(jest.isMockFunction(React)).toBe(false);
expect(jest.isMockFunction(React.lazy)).toBe(true);
expect(jest.isMockFunction(React2)).toBe(false);
expect(jest.isMockFunction(React2.lazy)).toBe(true);
);
);





share|improve this answer

























  • Thanks for detailed answer. Sadly, this won't work for my case because the problem is to mock named imports. Things could be simpler for default import React from 'react' but I'm not using it. React imports are most often used as import React, lazy from 'react', where React default export is used only by Babel/TS to provide React.createElement for JSX transform.

    – Estus Flask
    Mar 24 at 22:19












  • Do you mean something like import * as React from 'react'; React.lazy = jest.fn()? This won't work due to how Babel's ES module interop works for *.

    – Estus Flask
    Mar 24 at 22:58











  • Figured it out for named exports. Updated the answer to include both.

    – Matt Carlotta
    Mar 24 at 23:49












  • Thanks, that's the way I'm doing this now.

    – Estus Flask
    Mar 25 at 9:44













1












1








1







Default Imports:



A simple solution would be to mock React.lazy in the setupTest.js:



import React from 'react';
import configure from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
configure( adapter: new Adapter() );

jest.spyOn(React.lazy);


Any subsequent require/imports of react will be partially mocked for each test file.



Working example: https://github.com/mattcarlotta/react-lazy-mocked (I don't use the create-react-app, but jest can be set up the same way as I have it)



Installation:



  • git clone git@github.com:mattcarlotta/react-lazy-mocked.git

  • cd react-lazy-mocked

  • yarn install

  • yarn test


root/__tests__/root.test.js



import React from 'react';
import App from '../index.js';

const React2 = require('react');

describe('App', () =>
const wrapper = mount(<App />);

it('renders without errors', () =>
const homeComponent = wrapper.find('.app');
expect(homeComponent).toHaveLength(1);
);

it('should partially mock React module', async () =>
expect(jest.isMockFunction(await require('react').lazy)).toBe(true); // eslint-disable-line global-require
expect(jest.isMockFunction(React)).toBe(false);
expect(jest.isMockFunction(React.lazy)).toBe(true);
expect(jest.isMockFunction(React2)).toBe(false);
expect(jest.isMockFunction(React2.lazy)).toBe(true);
);

it('should no longer be partially mocked within the test file', () =>
React.lazy.mockRestore();
expect(jest.isMockFunction(React.lazy)).toBe(false);
);
);


pages/Home/__tests__/Home.test.js



import React from 'react';
import Home from '../index.js';

describe('Home', () =>
const wrapper = shallow(<Home />);

it('renders without errors', () =>
const homeComponent = wrapper.find('.app');
expect(homeComponent).toHaveLength(1);
);

it('should partially mock React module', async () =>
expect(jest.isMockFunction(React.lazy)).toBe(true);
);
);



Named Imports:



Working example: https://github.com/mattcarlotta/named-react-lazy-mocked



Installation:



  • git clone git@github.com:mattcarlotta/named-react-lazy-mocked.git

  • cd named-react-lazy-mocked

  • yarn install

  • yarn test

utils/__mocks__/react.js



jest.mock('react', () => (
...require.requireActual('react'),
lazy: jest.fn(),
));
module.exports = require.requireMock('react');


utils/setup/setupTest.js (optionally, you can add the mocked react file as a global jest function so you won't have to write import * as React from 'react' for every test):



import JSDOM from 'jsdom';
import configure from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
// import React from '../__mocks__/react';

configure( adapter: new Adapter() );

// global.React = React;


root/__tests__/root.test.js



import * as React from 'react';
import App from '../index.js';

const React2 = require('react');

describe('App', () =>
const wrapper = mount(<App />);

it('renders without errors', () =>
const homeComponent = wrapper.find('.app');
expect(homeComponent).toHaveLength(1);
);

it('should partially mock React module', async () =>
expect(jest.isMockFunction(await require('react').lazy)).toBe(true); // eslint-disable-line global-require
expect(jest.isMockFunction(React)).toBe(false);
expect(jest.isMockFunction(React.lazy)).toBe(true);
expect(jest.isMockFunction(React2)).toBe(false);
expect(jest.isMockFunction(React2.lazy)).toBe(true);
);
);





share|improve this answer















Default Imports:



A simple solution would be to mock React.lazy in the setupTest.js:



import React from 'react';
import configure from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
configure( adapter: new Adapter() );

jest.spyOn(React.lazy);


Any subsequent require/imports of react will be partially mocked for each test file.



Working example: https://github.com/mattcarlotta/react-lazy-mocked (I don't use the create-react-app, but jest can be set up the same way as I have it)



Installation:



  • git clone git@github.com:mattcarlotta/react-lazy-mocked.git

  • cd react-lazy-mocked

  • yarn install

  • yarn test


root/__tests__/root.test.js



import React from 'react';
import App from '../index.js';

const React2 = require('react');

describe('App', () =>
const wrapper = mount(<App />);

it('renders without errors', () =>
const homeComponent = wrapper.find('.app');
expect(homeComponent).toHaveLength(1);
);

it('should partially mock React module', async () =>
expect(jest.isMockFunction(await require('react').lazy)).toBe(true); // eslint-disable-line global-require
expect(jest.isMockFunction(React)).toBe(false);
expect(jest.isMockFunction(React.lazy)).toBe(true);
expect(jest.isMockFunction(React2)).toBe(false);
expect(jest.isMockFunction(React2.lazy)).toBe(true);
);

it('should no longer be partially mocked within the test file', () =>
React.lazy.mockRestore();
expect(jest.isMockFunction(React.lazy)).toBe(false);
);
);


pages/Home/__tests__/Home.test.js



import React from 'react';
import Home from '../index.js';

describe('Home', () =>
const wrapper = shallow(<Home />);

it('renders without errors', () =>
const homeComponent = wrapper.find('.app');
expect(homeComponent).toHaveLength(1);
);

it('should partially mock React module', async () =>
expect(jest.isMockFunction(React.lazy)).toBe(true);
);
);



Named Imports:



Working example: https://github.com/mattcarlotta/named-react-lazy-mocked



Installation:



  • git clone git@github.com:mattcarlotta/named-react-lazy-mocked.git

  • cd named-react-lazy-mocked

  • yarn install

  • yarn test

utils/__mocks__/react.js



jest.mock('react', () => (
...require.requireActual('react'),
lazy: jest.fn(),
));
module.exports = require.requireMock('react');


utils/setup/setupTest.js (optionally, you can add the mocked react file as a global jest function so you won't have to write import * as React from 'react' for every test):



import JSDOM from 'jsdom';
import configure from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
// import React from '../__mocks__/react';

configure( adapter: new Adapter() );

// global.React = React;


root/__tests__/root.test.js



import * as React from 'react';
import App from '../index.js';

const React2 = require('react');

describe('App', () =>
const wrapper = mount(<App />);

it('renders without errors', () =>
const homeComponent = wrapper.find('.app');
expect(homeComponent).toHaveLength(1);
);

it('should partially mock React module', async () =>
expect(jest.isMockFunction(await require('react').lazy)).toBe(true); // eslint-disable-line global-require
expect(jest.isMockFunction(React)).toBe(false);
expect(jest.isMockFunction(React.lazy)).toBe(true);
expect(jest.isMockFunction(React2)).toBe(false);
expect(jest.isMockFunction(React2.lazy)).toBe(true);
);
);






share|improve this answer














share|improve this answer



share|improve this answer








edited Mar 25 at 0:44

























answered Mar 24 at 22:04









Matt CarlottaMatt Carlotta

4,7062714




4,7062714












  • Thanks for detailed answer. Sadly, this won't work for my case because the problem is to mock named imports. Things could be simpler for default import React from 'react' but I'm not using it. React imports are most often used as import React, lazy from 'react', where React default export is used only by Babel/TS to provide React.createElement for JSX transform.

    – Estus Flask
    Mar 24 at 22:19












  • Do you mean something like import * as React from 'react'; React.lazy = jest.fn()? This won't work due to how Babel's ES module interop works for *.

    – Estus Flask
    Mar 24 at 22:58











  • Figured it out for named exports. Updated the answer to include both.

    – Matt Carlotta
    Mar 24 at 23:49












  • Thanks, that's the way I'm doing this now.

    – Estus Flask
    Mar 25 at 9:44

















  • Thanks for detailed answer. Sadly, this won't work for my case because the problem is to mock named imports. Things could be simpler for default import React from 'react' but I'm not using it. React imports are most often used as import React, lazy from 'react', where React default export is used only by Babel/TS to provide React.createElement for JSX transform.

    – Estus Flask
    Mar 24 at 22:19












  • Do you mean something like import * as React from 'react'; React.lazy = jest.fn()? This won't work due to how Babel's ES module interop works for *.

    – Estus Flask
    Mar 24 at 22:58











  • Figured it out for named exports. Updated the answer to include both.

    – Matt Carlotta
    Mar 24 at 23:49












  • Thanks, that's the way I'm doing this now.

    – Estus Flask
    Mar 25 at 9:44
















Thanks for detailed answer. Sadly, this won't work for my case because the problem is to mock named imports. Things could be simpler for default import React from 'react' but I'm not using it. React imports are most often used as import React, lazy from 'react', where React default export is used only by Babel/TS to provide React.createElement for JSX transform.

– Estus Flask
Mar 24 at 22:19






Thanks for detailed answer. Sadly, this won't work for my case because the problem is to mock named imports. Things could be simpler for default import React from 'react' but I'm not using it. React imports are most often used as import React, lazy from 'react', where React default export is used only by Babel/TS to provide React.createElement for JSX transform.

– Estus Flask
Mar 24 at 22:19














Do you mean something like import * as React from 'react'; React.lazy = jest.fn()? This won't work due to how Babel's ES module interop works for *.

– Estus Flask
Mar 24 at 22:58





Do you mean something like import * as React from 'react'; React.lazy = jest.fn()? This won't work due to how Babel's ES module interop works for *.

– Estus Flask
Mar 24 at 22:58













Figured it out for named exports. Updated the answer to include both.

– Matt Carlotta
Mar 24 at 23:49






Figured it out for named exports. Updated the answer to include both.

– Matt Carlotta
Mar 24 at 23:49














Thanks, that's the way I'm doing this now.

– Estus Flask
Mar 25 at 9:44





Thanks, that's the way I'm doing this now.

– Estus Flask
Mar 25 at 9:44



















draft saved

draft discarded
















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid


  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55327095%2fpartially-mock-react-module-with-jest%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Kamusi Yaliyomo Aina za kamusi | Muundo wa kamusi | Faida za kamusi | Dhima ya picha katika kamusi | Marejeo | Tazama pia | Viungo vya nje | UrambazajiKuhusu kamusiGo-SwahiliWiki-KamusiKamusi ya Kiswahili na Kiingerezakuihariri na kuongeza habari

Swift 4 - func physicsWorld not invoked on collision? The Next CEO of Stack OverflowHow to call Objective-C code from Swift#ifdef replacement in the Swift language@selector() in Swift?#pragma mark in Swift?Swift for loop: for index, element in array?dispatch_after - GCD in Swift?Swift Beta performance: sorting arraysSplit a String into an array in Swift?The use of Swift 3 @objc inference in Swift 4 mode is deprecated?How to optimize UITableViewCell, because my UITableView lags

Access current req object everywhere in Node.js ExpressWhy are global variables considered bad practice? (node.js)Using req & res across functionsHow do I get the path to the current script with Node.js?What is Node.js' Connect, Express and “middleware”?Node.js w/ express error handling in callbackHow to access the GET parameters after “?” in Express?Modify Node.js req object parametersAccess “app” variable inside of ExpressJS/ConnectJS middleware?Node.js Express app - request objectAngular Http Module considered middleware?Session variables in ExpressJSAdd properties to the req object in expressjs with Typescript