问题
I only want to mock a single function (named export) from a module but leave the rest of the module functions intact.
Using jest.mock('package-name')
makes all exported functions mocks, which I don't want.
I tried spreading the named exports back into the mock object...
import * as utils from './utilities.js';
jest.mock(utils, () => ({
...utils
speak: jest.fn(),
}));
but got this error:
The module factory of
jest.mock()
is not allowed to reference any out-of-scope variables.
回答1:
The highlight of this answer is jest.requireActual(), this is a very useful utility that says to jest that "Hey keep every original functionalities intact and import them".
jest.mock('./utilities.js', () => ({
...jest.requireActual('./utilities.js'),
speak: jest.fn(),
}));
Let's take another common scenario, you're using enzyme ShallowWrapper and it doesn't goes well with useContext() hook, so what're you gonna do? While i'm sure there are multiple ways, but this is the one I like:
import React from "react";
jest.mock("react", () => ({
...jest.requireActual("react"), // import and retain the original functionalities
useContext: jest.fn().mockReturnValue({foo: 'bar'}) // overwrite useContext
}))
The perk of doing it this way is that you can still use
import React, { useContext } from "react"
in your original code without worrying about converting them into React.useContext() as you would if you're using jest.spyOn(React, 'useContext')
回答2:
The most straightforward way is to use jest.spyOn
and then .mockImplementation()
. This will allow all other functions in the module to continue working how they're defined.
For packages:
import axios from 'axios';
jest.spyOn(axios, 'get');
axios.get.mockImplementation(() => { /* do thing */ });
For modules with named exports:
import * as utils from './utilities.js';
jest.spyOn(utils, 'speak');
utils.speak.mockImplementation(() => { /* do thing */ });
Docs here: https://jestjs.io/docs/en/jest-object#jestspyonobject-methodname
回答3:
For me this worked:
const utils = require('./utilities.js');
...
jest.spyOn(utils, 'speak').mockImplementation(() => jest.fn());
来源:https://stackoverflow.com/questions/59312671/mock-only-one-function-from-module-but-leave-rest-with-original-functionality