admin管理员组文章数量:1303404
How can the instance methods be mocked for a class that is being mocked with jest.mock
?
For example, a class Logger
is mocked:
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();
});
});
How can the instance methods be mocked for a class that is being mocked with jest.mock
?
For example, a class Logger
is mocked:
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();
});
});
Share
edited May 17, 2022 at 19:44
Som Shekhar Mukherjee
8,1682 gold badges15 silver badges32 bronze badges
asked May 17, 2022 at 19:05
surajs02surajs02
4712 gold badges8 silver badges20 bronze badges
4
-
have yout tried
import Logger from jest.mock("./Logger")
? – Some random IT boy Commented May 17, 2022 at 19:15 -
that gives the error
String literal expected
– surajs02 Commented May 17, 2022 at 19:16 -
Sorry, I meant
const Logger = jest.mock("./Logger")
– Some random IT boy Commented May 17, 2022 at 19:21 -
That makes sense but
Logger.method1
gives errorProperty 'method' does not exist on type '"./Logger"'
– surajs02 Commented May 17, 2022 at 19:23
1 Answer
Reset to default 5Automatic Mocking
Calling jest.mock
automatically mocks all the exports from the module being mocked unless a manual mock is specified using the __mocks__
directory.
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.
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.
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();
});
});
Using Module Factory Parameter
You can also explicitly provide a module factory by passing in a factory function as the second argument to jest.mock
. So, now the provided module factory would be used instead of Jest's automocking feature. 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
. And because of this we can access mockMethod1
inside the factory.
Manual Mock
You can achieve a similar behavior to module factory function by creating a manual mock located at __mocks__/Logger.js
. And now this mock implementation can be used across test files by simply calling 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__
.
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();
});
});
本文标签: javascriptHow to mock instance methods of a class mocked with jestmockStack Overflow
版权声明:本文标题:javascript - How to mock instance methods of a class mocked with jest.mock? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741688837a2392601.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论