[英]How to mock instance methods of a class mocked with jest.mock?
How can the instance methods be mocked for a class that is being mocked with jest.mock
?如何为使用
jest.mock
的类模拟实例方法?
For example, a class Logger
is mocked:例如,一个类
Logger
被模拟:
import Person from "./Person";
import Logger from "./Logger";
jest.mock("./Logger");
describe("Person", () => {
it("calls Logger.method1() on instantiation", () => {
Logger.method1.mockImplementation(() => {}) // This fails as `method1` is an instance method but how can the instance method be mocked here?
new Person();
expect(Logger.method1).toHaveBeenCalled();
});
});
Calling jest.mock
automatically mocks all the exports from the module being mocked unless a manual mock is specified using the __mocks__
directory.调用
jest.mock
自动模拟来自被模拟模块的所有导出,除非使用__mocks__
目录指定手动模拟。
So, this line jest.mock("./Logger")
has automatically replaced the Logger
constructor and all of it's methods with mock functions allowing us to test how these functions behave.所以,这行
jest.mock("./Logger")
已经自动替换了Logger
构造函数和它的所有方法与模拟函数允许我们测试这些函数的行为方式。
And the information related to the instances created by Logger
is saved in Logger.mock.instances
, so we can use this to test if the methods are being called properly. Logger
创建的实例相关信息保存在Logger.mock.instances
中,因此我们可以使用它来测试方法是否被正确调用。
import Person from "./Person";
import Logger from "./Logger";
jest.mock("./Logger");
describe("Person", () => {
it("calls method1 on instantiation", () => {
const p = new Person();
// Logger constructor should have been called
expect(Logger).toHaveBeenCalled();
const mockLoggerInstance = Logger.mock.instances[0];
const mockMethod1 = mockLoggerInstance.method1;
// method1 should have also been called
expect(mockMethod1).toHaveBeenCalled();
});
});
You can also explicitly provide a module factory by passing in a factory function as the second argument to jest.mock
.您还可以通过将工厂函数作为第二个参数传递给
jest.mock
来显式提供模块工厂。 So, now the provided module factory would be used instead of Jest's automocking feature.因此,现在将使用提供的模块工厂来代替 Jest 的自动模拟功能。 Refer the docs for more information.
有关更多信息,请参阅文档。
import Person from "./Person";
import Logger from "./Logger";
const mockMethod1 = jest.fn();
jest.mock("./Logger", () =>
jest.fn().mockImplementation(() => ({
method1: mockMethod1,
}))
);
describe("Person", () => {
it("calls method1 on instantiation", () => {
const p = new Person();
// Logger constructor should have been called
expect(Logger).toHaveBeenCalled();
// method1 should have also been called
expect(mockMethod1).toHaveBeenCalled();
});
});
Note: jest.mock()
calls are hoisted, so you cannot first define a variable and then use it inside a factory function unless the variable is prefixed with mock
.注意:
jest.mock()
调用被提升,所以你不能先定义一个变量然后在工厂函数中使用它,除非变量以mock
为前缀。 And because of this we can access mockMethod1
inside the factory.正因为如此,我们可以访问工厂内部的
mockMethod1
。
You can achieve a similar behavior to module factory function by creating a manual mock located at __mocks__/Logger.js
.您可以通过创建位于
__mocks__/Logger.js
的手动模拟来实现与模块工厂功能类似的行为。 And now this mock implementation can be used across test files by simply calling jest.mock
.现在这个模拟实现可以通过简单地调用
jest.mock
来跨测试文件使用。
// __mocks__/Logger.js
const mockMethod1 = jest.fn();
const mockLogger = jest.fn(() => ({
method1: mockMethod1,
}));
Usage is similar to the module factory function but you now also have to import the mocked method in your test.用法类似于模块工厂函数,但您现在还必须在测试中导入模拟方法。
Note: You still need to use the original module path, don't include __mocks__
.注意:您仍然需要使用原始模块路径,不要包含
__mocks__
。
import Person from "./Person";
import Logger, { mockMethod1 } from "./Logger";
jest.mock("./Logger");
describe("Person", () => {
it("calls method1 on instantiation", () => {
const p = new Person();
// Logger constructor should have been called
expect(Logger).toHaveBeenCalled();
// method1 should have also been called
expect(mockMethod1).toHaveBeenCalled();
});
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.