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?