Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Typescript errors when using jest mocks

I have a previously-created .js file that mocks away some of our functions for jest test purposes. I'm migrating that to a .ts file:

Server.ts

const Server = jest.genMockFromModule('../Server');

Server.getAsync = Server.default.getAsync;
// other REST-ful functions here

export default Server;

I am getting the following errors:

Property 'getAsync' does not exist on type '{}'

Property 'default' does not exist on type '{}'

Then, in a corresponding test file:

MyComponent.test.ts

import Server from 'path/to/Server';

jest.mock('path/to/Server');

const dispatchMock = jest.fn();
const getStateMock = jest.fn();

describe('MyComponent.someFunction', () => {
    beforeEach(() => {
        jest.resetAllMocks();
    });

    it('Does the right stuff', () => {
        Server.getAsync.mockReturnValueOnce(Promise.resolve([{ key: 'value' }]));
        dispatchMock.mockImplementationOnce((promise) => promise);
        dispatchMock.mockImplementationOnce();

        return someFunction()(dispatchMock)
            .then(() => {
                expect(Server.getAsync).toHaveBeenCalledTimes(1);
                expect(Server.getAsync.mock.calls[0][0]).toBe('something');
            });
    });
});

I am getting errors on dispatchMock.mockImplementationOnce()

Expected 1 arguments, but got 0. (method) jest.MockInstance<{}>.mockImplementationOnce(fn: (...args: any[]) => any): jest.Mock<{}>

...on Server.getAsync.mockReturnValueOnce

Property 'mockReturnValueOnce' does not exist on type '(url: string, baseRoute?: string | null, loadingGenerator?: (isLoading: boolean) => { type: strin...'.

...and on Server.getAsync.mock

Property 'mock' does not exist on type '(url: string, baseRoute?: string | null, loadingGenerator?: (isLoading: boolean) => { type: strin...'.

I've been pounding my head on this for a while so any help would be greatly appreciated.

UPDATE

Okay, I added as any to the end of the first line of my Server.ts file so now it looks like:

const Server = jest.genMockFromModule('../Server') as any;

That got rid of the first set of errors. Still facing the errors in my .test.ts file though.

UPDATE 2

I've noticed that when I run the actual jest tests, that they all pass even though there are TypeErrors. These issues don't appear to be related to actual tests.

like image 881
noblerare Avatar asked Jul 06 '18 18:07

noblerare


3 Answers

I fixed this myself. The way that I got it to work was to cast any calls to Server.getAsync to the specific jest mock type.

let getAsyncMock = Server.getAsync as jest.Mock

or

let getAsyncMock = <jest.Mock>(Server.getAsync)

This gets rid of my errors.

like image 136
noblerare Avatar answered Nov 04 '22 11:11

noblerare


Following the @nobleare response... a good update will be to wrap your mock implementation into the beforeAll and clear it into the beforeEach block:

import { AnalyticsApi } from "../../api/src";

jest.mock("../../api/src");

describe('...', () => {

  beforeAll(() => {
    (AnalyticsApi as jest.Mock<AnalyticsApi>).mockImplementation(() => ({
      listPolicies: jest.fn().mockResolvedValue('promiseValue')
    }));
  });

  beforeEach(() => {
    (AnalyticsApi as jest.Mock<AnalyticsApi>).mockClear();
  });

});
like image 37
iarroyo Avatar answered Nov 04 '22 11:11

iarroyo


Use this

import { mocked } from 'ts-jest/utils';
import { foo } from './foo';
jest.mock('./foo');


expect(mocked(foo)).toHaveLength(1);
like image 4
Bohdan Other Avatar answered Nov 04 '22 10:11

Bohdan Other