Как сильно печатать шутки
Я хотел бы сильно напечатать мои шутки. В определенной степени я могу заставить это работать, но когда у класса есть личные свойства, я застреваю.
Дополнительный вопрос: когда я использую mocks (так, как я это делаю в настоящее время), возвращаемый тип имеет исходный тип, но когда мне нужно получить доступ к любому методу, добавленному Jest, я должен выполнить его так jest.Mock
чтобы получить доступ к методу. Есть лучший способ сделать это? Я пытался работать с jest.Mock
, jest.Mocked
, jest.MockInstance
,
Если бы кто-нибудь мог указать мне правильное направление, это было бы здорово!
class MyTest {
constructor(private readonly msg: string) {}
public foo(): string {
return this.msg;
}
}
const myTestMock: jest.Mock<MyTest, [string]> = jest.fn<MyTest, [string]>(() => ({
msg: 'private',
foo: jest.fn().mockReturnValue('aaa'),
}));
// Results in error:
// Type '{ msg: string; foo: Mock<any, any>; }' is not assignable to type 'MyTest'.
// Property 'msg' is private in type 'MyTest' but not in type '{ msg: string; foo: Mock<any, any>; }'
const myTestMockInstance: MyTest = new myTestMock('a');
console.log(myTestMockInstance.foo()); // --> aaa
// Accessing jest mock methods:
(<jest.Mock>myTestMockInstance).mockClear(); // <-- can this be done without type casting
Грязный обходной путь:
const myTestMock: jest.Mock<MyTest, [string]> = jest.fn<MyTest, [string]>(
// Cast to any to satisfy TS
(): any => ({
msg: 'private',
foo: jest.fn().mockReturnValue('aaa'),
})
);
3 ответа
Существует библиотека, которая может помочь вам со строго типизированными макетами в Typescript с Jest: jest-mock-extended
Я не уверен, что вам нужен доступ к частным свойствам вашего макета. Как говорит Ким Керн, вас должен интересовать только общедоступный интерфейс зависимости тестируемого модуля.
jest-mock-extended содержит
mock()
метод, который возвращает
MockProxy
что позволяет получить доступ
.mockReturnValue()
и Т. Д.
import { mock } from "jest-mock-extended";
interface WidgetService {
listMyWidgets(): { id: string }[];
};
const mockedService = mock<WidgetService>();
mockedService.listMyWidgets.mockReturnValue([{ id: 'widget-1' }]);
Есть помощник, который делает типы: смотри ts-jest
обычно вам следует тестировать публичный интерфейс, а не реализацию. Вместо тестирования частных методов вы можете извлечь эту логику в общедоступный интерфейс (возможно, в другой класс, который предоставляет интерфейс)
Вы можете использовать
jest.fn()
чтобы имитировать создание экземпляра объекта класса и опустить указание типа переменной и позволить Typescript вывести его.
myTestMockInstance
не будет иметь типа
MyTest
потому что ты издеваешься.
class MyTest {
constructor(private readonly msg: string) {}
public foo(): string {
return this.msg
}
}
const myTestMock = jest.fn((msg: string) => ({
msg,
foo() {
return this.msg
}
}))
const myTestMockInstance = new myTestMock('a')
console.log(myTestMockInstance.foo()) // --> a