spe*_*.sm 72 javascript unit-testing jestjs
我只想模拟模块中的单个函数(名为导出),但保持模块的其余功能完好无损。
使用jest.mock('package-name')使所有导出的函数模拟,这是我不想要的。
我尝试将命名导出传播回模拟对象...
import * as utils from './utilities.js';
jest.mock(utils, () => ({
...utils
speak: jest.fn(),
}));
Run Code Online (Sandbox Code Playgroud)
但得到这个错误:
的模块工厂
jest.mock()不允许引用任何范围外的变量。
小智 113
这个答案的亮点是jest.requireActual(),这是一个非常有用的实用程序,可以开玩笑说“嘿保持每个原始功能完好无损并导入它们”。
jest.mock('./utilities.js', () => ({
...jest.requireActual('./utilities.js'),
speak: jest.fn(),
}));
Run Code Online (Sandbox Code Playgroud)
让我们再看一个常见的场景,你正在使用酶 ShallowWrapper 并且它不适合 useContext() 钩子,那么你打算怎么做?虽然我确定有多种方法,但这是我喜欢的一种:
import React from "react";
jest.mock("react", () => ({
...jest.requireActual("react"), // import and retain the original functionalities
useContext: jest.fn().mockReturnValue({foo: 'bar'}) // overwrite useContext
}))
Run Code Online (Sandbox Code Playgroud)
这样做的好处是您仍然可以import React, { useContext } from "react"在原始代码中使用
,而无需担心将它们转换为React.useContext(),就像您使用jest.spyOn(React, 'useContext')
spe*_*.sm 34
最直接的方法是使用jest.spyOn然后.mockImplementation()。这将允许模块中的所有其他函数继续按照定义的方式工作。
对于包裹:
import axios from 'axios';
jest.spyOn(axios, 'get');
axios.get.mockImplementation(() => { /* do thing */ });
Run Code Online (Sandbox Code Playgroud)
对于具有命名导出的模块:
import * as utils from './utilities.js';
jest.spyOn(utils, 'speak');
utils.speak.mockImplementation(() => { /* do thing */ });
Run Code Online (Sandbox Code Playgroud)
文档在这里:https : //jestjs.io/docs/en/jest-object#jestspyonobject-methodname
Ric*_*ler 17
jest.requireActual内部jest.mock似乎是可行的方法,但是我需要添加代理而不是对象传播,以防止Cannot read properties of undefined (reading ...)在某些导入场景中可能发生的类型错误。
这是最终结果:
jest.mock('the-module-to-mock', () => {
const actualModule = jest.requireActual('the-module-to-mock')
return new Proxy(actualModule, {
get: (target, property) => {
switch (property) {
// add cases for exports you want to mock
//
case 'foo': {
return jest.fn() // add `mockImplementation` etc
}
case 'bar': {
return jest.fn()
}
// fallback to the original module
default: {
return target[property]
}
}
},
})
})
Run Code Online (Sandbox Code Playgroud)
小智 8
对我来说这有效:
const utils = require('./utilities.js');
...
jest.spyOn(utils, 'speak').mockImplementation(() => jest.fn());
Run Code Online (Sandbox Code Playgroud)
我采纳了 Rico Kahler 的答案并创建了这个通用函数:
function mockPartially(packageName: string, getMocks: (actualModule: any) => any) {
jest.doMock(packageName, () => {
const actualModule = jest.requireActual(packageName);
const mocks = getMocks(actualModule);
return new Proxy(actualModule, {
get: (target, property) => {
if (property in mocks) {
return mocks[property];
} else {
return target[property];
}
},
});
});
}
Run Code Online (Sandbox Code Playgroud)
你可以像这样使用它来模拟 lodash:
mockPartially('lodash', (_actualLodash) => { //sometimes you need the actual module
return {
'isObject': () => true, //mock isObject
'isArray': () => true // mock isArray
}
});
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
28396 次 |
| 最近记录: |