Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
410 views
in Technique[技术] by (71.8m points)

javascript - Mock dependency in Jest with TypeScript

When testing a module that has a dependency in a different file and assigning that module to be a jest.mock, TypeScript gives an error that the method mockReturnThisOnce (or any other jest.mock method) does not exist on the dependency, this is because it is previously typed.

What is the proper way to get TypeScript to inherit the types from jest.mock?

Here is a quick example.

Dependency

const myDep = (name: string) => name;
export default myDep;

test.ts

import * as dep from '../depenendency';
jest.mock('../dependency');

it('should do what I need', () => {
  //this throws ts error
  // Property mockReturnValueOnce does not exist on type (name: string)....
  dep.default.mockReturnValueOnce('return')
}

I feel like this is a very common use case and not sure how to properly type this.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You can use type casting and your test.ts should look like this:

import * as dep from '../dependency';
jest.mock('../dependency');

const mockedDependency = <jest.Mock<typeof dep.default>>dep.default;

it('should do what I need', () => {
  //this throws ts error
  // Property mockReturnValueOnce does not exist on type (name: string)....
  mockedDependency.mockReturnValueOnce('return');
});

TS transpiler is not aware that jest.mock('../dependency'); changes type of dep thus you have to use type casting. As imported dep is not a type definition you have to get its type with typeof dep.default.

Here are some other useful patterns I've found during my work with Jest and TS

When imported element is a class then you don't have to use typeof for example:

import { SomeClass } from './SomeClass';

jest.mock('./SomeClass');

const mockedClass = <jest.Mock<SomeClass>>SomeClass;

This solution is also useful when you have to mock some node native modules:

import { existsSync } from 'fs';

jest.mock('fs');

const mockedExistsSync = <jest.Mock<typeof existsSync>>existsSync;

In case you don't want to use jest automatic mock and prefer create manual one

import TestedClass from './TestedClass';
import TestedClassDependency from './TestedClassDependency';

const testedClassDependencyMock = jest.fn<TestedClassDependency>(() => ({
  // implementation
}));

it('Should throw an error when calling playSomethingCool', () => {
  const testedClass = new TestedClass(testedClassDependencyMock());
});

testedClassDependencyMock() creates mocked object instance TestedClassDependency can be either class or type or interface


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...