Cod*_*rit 78 typescript reactjs jestjs spyon
我有UserContext一个useUser从 导出的钩子src/app/context/user-context.tsx。另外,我有一个 index.tsx 文件,其中src/app/context导出所有子模块。
如果我监视src/app/context/user-context它,但将导入更改为src/app/context我得到:
TypeError: Cannot redefine property: useUser at Function.defineProperty (<anonymous>)
Run Code Online (Sandbox Code Playgroud)
这是为什么?
源代码:
TypeError: Cannot redefine property: useUser at Function.defineProperty (<anonymous>)
Run Code Online (Sandbox Code Playgroud)
// src/app/context/user-context.tsx
export const UserContext = React.createContext({});
export function useUser() {
return useContext(UserContext);;
}
Run Code Online (Sandbox Code Playgroud)
// src/app/context/index.tsx
export * from "./user-context";
Run Code Online (Sandbox Code Playgroud)
Spe*_*ord 96
不同意使用jest.mock()代替spyOn()是一个好的解决方案。使用这种方法,您必须在规范文件的顶部模拟所有函数。
但某些测试用例可能需要不同的设置或保持真实。
无论如何,我想继续使用spyOn()。
更好的方法是在规范文件的顶部添加以下行(就在导入之后和之前describe())。
import * as Foo from 'path/to/file';
jest.mock('path/to/file', () => {
return {
__esModule: true, // <----- this __esModule: true is important
...jest.requireActual('path/to/file')
};
});
...
//just do a normal spyOn() as you did before somewhere in your test:
jest.spyOn(Foo, 'fn');
Run Code Online (Sandbox Code Playgroud)
PS 也可以是一句单行话:
jest.mock('path/to/file', () => ({ __esModule: true, ...jest.requireActual('path/to/file') }));
Run Code Online (Sandbox Code Playgroud)
PPS 设置'path/to/file'为常量可能不起作用。至少对我来说没有。遗憾的是,您需要重复实际路径 3 次。
die*_*edu 41
如果你看一下为重新导出生成的js 代码,它看起来像这样
Object.defineProperty(exports, "__esModule", {
value: true
});
var _context = require("context");
Object.keys(_context).forEach(function (key) {
if (key === "default" || key === "__esModule") return;
if (key in exports && exports[key] === _context[key]) return;
Object.defineProperty(exports, key, {
enumerable: true,
get: function get() {
return _context[key];
}
});
});
Run Code Online (Sandbox Code Playgroud)
您得到的错误是由于编译器没有添加 的configurable: true选项defineProperty,这将允许笑话重新定义导出以模拟它,来自文档
可配置
如果可以更改此属性描述符的类型并且可以从相应的对象中删除该属性,则为true 。默认为
false.
我认为您可以以某种方式调整您的配置以使编译器添加该配置,但这完全取决于您使用的工具。
更容易访问的方法是使用jest.mock而不是jest.spyOn模拟用户上下文文件,而不是尝试重新定义不可配置的导出
it("should render complete navigation when user is logged in", () => {
jest.mock('./user-context', () => {
return {
...jest.requireActual('./user-context'),
useUser: jest.fn().mockReturnValue({
user: {},
update: (user: any) => null,
initialized: true
})
}
})
});
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
74353 次 |
| 最近记录: |