#typescript, #jestjs, #typescript-typings, #ts-jest,
To strongly type my jest mocks. To a certain extent, I can make it work.
When I use mocks (the way I currently do) the return type is of the original type but when I have to access any method added by Jest I have to typecast it so jest.Mock
to access a method.
I've tried to work with 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
Dirty workaround:
const myTestMock: jest.Mock<MyTest, [string]> = jest.fn<MyTest, [string]>(
// Cast to any to satisfy TS
(): any => ({
msg: 'private',
foo: jest.fn().mockReturnValue('aaa'),
})
);
xxxxxxxxxxThere is a helper which makes types: look ts-jest
usually you should test public interface, not an implementation. Instead of testing private methods you could extract that logic to a public interface (maybe to another class that provides the interface)