22
votes

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.

5

5 Answers

34
votes

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.

8
votes

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();
  });

});
4
votes

Use this

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


expect(mocked(foo)).toHaveLength(1);
2
votes

To override an import, you can do it like so:

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

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

let listPolicies = jest.fn(() => {
  return Promise.resolve();
});

(AnalyticsApi as jest.Mock<AnalyticsApi>).mockImplementation(() => ({
  listPolicies,
}));
1
votes

First of all, you're using genMockFromModule which creates a mock of your Server so there is no need to call jest.mock('path/to/Server');.

Second, what are you trying to achieve by doing Server.getAsync = Server.default.getAsync;? All that does is move the getAsync up a level which isn't necessary. You could just call jest.genMockFromModule('../Server').default;;

dispatchMock.mockImplementationOnce() is throwing that error because you said it requires a promise to be passed to it here: dispatchMock.mockImplementationOnce((promise) => promise);

For Server.getAsync.mockReturnValueOnce and Server.getAsync.mock you actually want to use mocked instead of casting the type like the other answers suggest.

Example: mocked(Server.getAsync).mockReturnValueOnce()