Suf*_*ane 76 javascript unit-testing node.js typescript jestjs
我收到错误:
ReferenceError: Cannot access 'myMock' before initialization
我正在这样做:
import MyClass from './my_class';
import * as anotherClass from './another_class';
const mockMethod1 = jest.fn();
const mockMethod2 = jest.fn();
jest.mock('./my_class', () => {
return {
default: {
staticMethod: jest.fn().mockReturnValue(
{
method1: mockMethod1,
method2: mockMethod2,
})
}
}
});
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,我的两个变量都遵循“标准”,但没有正确提升。
我错过了什么吗?
显然,当我只是传递jest.fn()
而不是我的变量时,它是有效的,但我不确定如何在稍后的测试中使用它们。
Mau*_*ius 68
上面的答案都没有解决我的问题,所以这是我的解决方案:
const mockMyMethod = jest.fn();
jest.mock('some-package', () => ({
myMethod: () => mockMyMethod()
}));
Run Code Online (Sandbox Code Playgroud)
编辑
之前的解决方案使用提升var
,但这是一个奇怪的解决方法。更新后的解决方案无需以 jest 满意的方式进行提升。它之所以有效,是因为在从模拟包调用mockMyMethod
该方法之前,该函数并未实际执行。myMethod
Jas*_*son 30
当您需要监视声明时,接受的答案不会处理const
,因为它是在模块工厂范围内定义的。
对我来说,模块工厂需要位于最终导入您想要模拟的内容的任何导入语句之上。这是使用带有prisma库的Nestjs的代码片段。
// app.e2e.spec.ts
import { Test, TestingModule } from '@nestjs/testing';
import { INestApplication } from '@nestjs/common';
import * as request from 'supertest';
import mockPrismaClient from './utils/mockPrismaClient'; // you can assert, spy, etc. on this object in your test suites.
// must define this above the `AppModule` import, otherwise the ReferenceError is raised.
jest.mock('@prisma/client', () => {
return {
PrismaClient: jest.fn().mockImplementation(() => mockPrismaClient),
};
});
import { AppModule } from './../src/app.module'; // somwhere here, the prisma is imported
describe('AppController (e2e)', () => {
let app: INestApplication;
beforeEach(async () => {
const moduleFixture: TestingModule = await Test.createTestingModule({
imports: [AppModule],
}).compile();
app = moduleFixture.createNestApplication();
await app.init();
});
)};
Run Code Online (Sandbox Code Playgroud)
Mat*_*att 24
为了澄清Jason Limantoro所说的内容,请将const
上面的内容移至导入模块的位置:
const mockMethod1 = jest.fn(); // Defined here before import.
const mockMethod2 = jest.fn();
import MyClass from './my_class'; // Imported here.
import * as anotherClass from './another_class';
jest.mock('./my_class', () => {
return {
default: {
staticMethod: jest.fn().mockReturnValue(
{
method1: mockMethod1,
method2: mockMethod2,
})
}
}
});
Run Code Online (Sandbox Code Playgroud)
Ric*_*lde 15
你应该把你的嘲笑移到你的导入之上;这可能是你的问题的根源。导入也会被提升,因此多个提升的条目将按顺序提升。
jest.mock('./my_class', () => {
const mockMethod = jest.fn()
const default = { staticMethod: jest.fn().mockReturnValue({ method: mockMethod }) };
return { default, mockMethod };
});
import MyClass, { mockMethod } from './my_class'; // will import your mock
import * as anotherClass from './another_class';
Run Code Online (Sandbox Code Playgroud)
但是,如果由于某种原因您无法做到这一点,您可以使用doMock
以避免提升行为。如果这种情况发生在文件的顶部,则应该是 1 比 1 的更改。
var mockMyMethod = jest.fn();
jest.doMock('some-package', () => ({ myMethod: mockMyMethod }));
Run Code Online (Sandbox Code Playgroud)
我还建议使用var
代替const
或let
用于模拟。他们的提升行为略有不同,我发现有几次使用var
似乎与 jest 自己的提升效果更好。
Est*_*ask 11
文档解决的问题是已jest.mock
提升但const
声明未提升。这会导致工厂函数在导入模拟模块时被评估,并且变量处于临时死区。
如果需要访问嵌套的模拟函数,则需要将它们作为导出对象的一部分公开:
jest.mock('./my_class', () => {
const mockMethod1 = jest.fn();
const mockMethod2 = jest.fn();
return {
__esModule: true,
mockMethod1,
mockMethod2,
default: {
...
Run Code Online (Sandbox Code Playgroud)
这也适用于手动模拟,其中__mocks__
变量只能在模拟内部访问。
我遇到了同样的问题。
ReferenceError:初始化前无法访问“mockYourFunction”
所选答案有效,但解释错误,不是因为 import order。它起作用的原因是因为答案更改mockResturnValue
为mockImplementation
.
mockResturnValue
将尝试立即解析该值,而
mockImplementation
仅在调用时才执行此操作,前提是变量在需要时需要时间。
一些,为了举例说明一个可行的解决方案,无需重新排序导入或添加 var 并避免在 PR 中出现一些激烈的评论,以下是代码的重要部分:
const mockPrismaClient = jest.fn();
jest.mock('@prisma/client', () => {
return {
PrismaClient: jest.fn().mockImplementation(() => mockPrismaClient),
};
});
Run Code Online (Sandbox Code Playgroud)