28

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 Answers 5

38

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.

Sign up to request clarification or add additional context in comments.

3 Comments

Did you find out a way to do this with imports? ie: import axios from 'axios'; jest.mock('axios');
Awesome answer. I did like (Server.getAsync as jest.Mock).mockImplementationOnce under each unit test and it worked.
This does not work with the latest version of typescript. I have to cast it to unknown first. i.e Server.getAsync as unknown as jest.Mock Does anyone know a way around this?
11

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

});

1 Comment

Thanks for that dude, the (AnalyticsApi as jest.Mock<AnalyticsApi>) or even (AnalyticsApi as jest.Mock) really helped me out!!
4

Use this

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


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

Comments

2

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

Comments

1

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.