我有以下情况:
- 在我的 .js 文件中,我导入了包 foo 的默认导出
- 此导出有两个属性 Bar 和 Baz,它们都是 ES6 类
- 在我的 .test.js 文件中,我现在想要模拟这两个类并监视它们的构造函数
.js 代码大致如下所示:
import foo from 'foo/dist/foo.min';
const { Bar, Baz } = foo;
...
const fooBar = new Bar();
在我的 .test.js 文件中,我现在像这样模拟包:
jest.mock('foo/dist/foo.min');
自动模拟按预期工作,但当然不允许我监视 Bar 和 Baz 的构造函数,这正是我想要的。
我尝试在我的 .test.js 文件中简单地执行此操作:
import foo from 'foo/dist/foo.min';
jest.mock('foo/dist/foo.min');
foo.Bar = jest.fn();
foo.Baz = jest.fn();
但这似乎没有做任何事情,我的假 jest.fn() 构造函数永远不会被调用。
我已在文档中阅读此页面:https://jestjs.io/docs/en/es6-class-mocks.html但似乎假设要模拟的 ES6 类是直接从模块导出的,并且位于项目内部,而不是 npm 包。
自动模拟对我不起作用,因为类不会自行导出。
- 我无法在 foo 包上使用
mockImplementation()
,因为它不是函数,对吗? - 我看不到进行手动模拟的方法,因为它是一个 npm 包。
如果有任何有关如何解决此问题的建议,我将不胜感激。
最佳答案
一些注意事项:
babel-jest
提升对jest.mock
的调用,以便它们首先发生。- automatic mock由
Jest
创建反射(reflect)了模块的结构。
因此调用 jest.mock('foo/dist/foo.min');
意味着 Jest
将为在此期间运行的任何代码自动模拟该模块测试,自动模拟将反射(reflect)原始模块的结构。
看起来您的代码一运行就调用了 Bar
构造函数。
这意味着以下测试应该有效:
import foo from 'foo/dist/foo.min'; // foo is already auto-mocked...
import './code'; // import your code (which calls the Bar constructor)
jest.mock('foo/dist/foo.min'); // ...because this runs first
test('constructor was called', () => {
expect(foo.Bar).toHaveBeenCalled(); // SUCCESS
})
<小时/>
看来您的测试不起作用,因为您在代码运行后设置了 foo.Bar = jest.fn();
(覆盖了之前的 >spy
当你的代码运行时确实被调用)。
关于javascript - 模拟类是从带有 jest 的包导入的对象的属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54789140/