Я хочу издеваться над реализацией класса, но затем выполнять утверждения о том, что методы были вызваны в моем тесте.
Ниже приведены результаты:
Error: expect(jest.fn()).toHaveBeenCalled()
Expected number of calls: >= 1
Received number of calls: 0
Я предполагаю, что здесь не работает мой вызов const service = new Service();
в тестовом файле, создающий новый экземпляр макета.
Как я могу имитировать классы, но обеспечить возврат одного и того же экземпляра, когда он создается в другом месте теста?
// ./service.ts
class Service {
getNothing() {
return null;
}
}
export { Service };
// ./controller.ts
import { Service } from './service';
export default async (): Promise<void> => {
const service = new Service();
console.info(`result: ${service.getNothing()}`);
};
// ./example.test.ts
import { Service } from './service';
import controller from './controller';
jest.mock('./service', () => {
return {
Service: jest.fn().mockImplementation(() => {
return {
getNothing: jest.fn(),
};
}),
};
});
describe('example test', () => {
test('example', async () => {
const service = new Service();
await controller();
expect(service.getNothing).toHaveBeenCalled();
});
});
Похоже, вы несколько раз вызываете издевательский конструктор и возвращаете несколько разных экземпляров издевательского объекта. Это означает, что expect(service.getNothing)
относится к методу, отличному от service.getNothing
, созданного в контроллере.
Вместо этого вам нужно убедиться, что одна и та же функция используется для имитации всех экземпляров getNothing
. К счастью, это легко сделать:
// ./example.test.ts
import { Service } from './service';
import controller from './controller';
// create our mock to assert on later
const mockedGetNothing = jest.fn();
jest.mock('./service', () => {
return {
Service: jest.fn().mockImplementation(() => {
return {
// return the same mock function for all instances of the module
getNothing: mockedGetNothing,
};
}),
};
});
describe('example test', () => {
test('example', async () => {
const service = new Service();
await controller();
// assert on the mocked function
expect(mockedGetNothing).toHaveBeenCalled();
});
});
Обратите внимание, что jest автоматически поднимет весь код мока модуля в начало файла перед любым импортом из-за того, как имитатор модуля работает за кулисами. Это может вызвать проблемы, если макеты используют переменные, определенные в тестовом файле, хотя, насколько мне известно, любые переменные с именами, начинающимися с mock
, также должны быть подняты.