user2298581
user2298581

Reputation: 672

Property 'mockResolvedValue' does not exist on type '<T = any, R = AxiosResponse<T>>

I'm trying to do the Mocking Module example on the Jest official documentation here: https://jestjs.io/docs/mock-functions

test('should fetch users', () => {
  const users = [{name: 'Bob'}];
  const resp = {data: users};
  axios.get.mockResolvedValue(resp);

  return Users.all().then(data => expect(data).toEqual(users));
});

but the mockResolvedValue gives me this typescript error:

Property 'mockResolvedValue' does not exist on type '<T = any, R = AxiosResponse>(url: string, config?: AxiosRequestConfig | undefined) => Promise'.ts(2339)

my dev dependency:

"devDependencies": {
    "@babel/cli": "7.13.0",
    "@babel/core": "7.12.17",
    "@babel/plugin-proposal-class-properties": "7.12.13",
    "@babel/preset-env": "7.12.17",
    "@babel/preset-react": "7.12.13",
    "@babel/preset-typescript": "7.12.17",
    "@jest/reporters": "26.6.2",
    "@types/axios": "0.14.0",
    "@types/jest": "26.0.20",
    "@types/luxon": "1.26.2",
    "@types/node": "14.14.35",
    "@types/react": "17.0.3",
    "@types/react-dom": "17.0.2",
    "@types/react-redux": "7.1.16",
    "@types/react-router": "5.1.12",
    "@types/react-router-dom": "5.1.7",
    "@types/redux-actions": "2.6.1",
    "@types/redux-logger": "3.0.8",
    "@types/redux-mock-store": "1.0.2",
    "@types/styled-components": "5.1.9",
    "@types/webpack-env": "1.16.0",
    "@types/yup": "0.29.9",
    "@typescript-eslint/eslint-plugin": "4.15.2",
    "@typescript-eslint/parser": "4.15.1",
    "axios": "0.21.1",
    "axios-hooks": "2.5.0",
    "babel-core": "7.0.0-bridge.0",
    "babel-eslint": "10.1.0",
    "babel-jest": "26.6.3",
    "babel-loader": "8.2.2",
    "babel-plugin-css-modules-transform": "1.6.2",
    "babel-plugin-inline-react-svg": "2.0.0",
    "backstopjs": "5.0.6",
    "cheerio": "0.22.0",
    "chokidar-cli": "2.1.0",
    "enzyme": "3.11.0",
    "enzyme-adapter-react-16": "1.15.6",
    "enzyme-to-json": "3.6.1",
    "eslint": "7.20.0",
    "eslint-config-prettier": "8.1.0",
    "eslint-config-react-app": "6.0.0",
    "eslint-plugin-flowtype": "5.2.2",
    "eslint-plugin-import": "2.22.1",
    "eslint-plugin-jest": "24.1.5",
    "eslint-plugin-jsx-a11y": "6.4.1",
    "eslint-plugin-prettier": "3.3.1",
    "eslint-plugin-react": "7.22.0",
    "eslint-plugin-react-hooks": "4.2.0",
    "j1r-react-scripts": "1.7.3",
    "j1r-wiremock-cli": "0.3.7",
    "jest": "26.6.3",
    "jest-environment-enzyme": "7.1.2",
    "jest-enzyme": "7.1.2",
    "jest-junit": "12.0.0",
    "jest-mock-promise": "1.1.10",
    "jest-resolve": "26.6.2",
    "jest-watch-typeahead": "0.6.1",
    "lighthouse": "7.1.0",
    "lint-staged": "10.5.4",
    "miragejs": "0.1.41",
    "nightwatch": "1.5.1",
    "npm-run-all": "4.1.5",
    "prettier": "2.2.1",
    "prop-types": "15.7.2",
    "react-app-rewire-babel-loader": "0.1.1",
    "react-app-rewired": "2.1.8",
    "react-scripts": "3.4.1",
    "redux-devtools-extension": "2.13.8",
    "redux-mock-store": "1.5.4",
    "sass-loader": "11.0.1",
    "selenium-server": "3.141.59",
    "sort-package-json": "1.49.0",
    "ts-mockito": "2.6.1",
    "typedoc": "0.19.2",
    "typescript": "4.2.2",
    "webpack": "5.23.0",
    "whatwg-fetch": "3.6.1",
    "react-app-rewire-alias": "1.0.1"
  },
  "jest-junit": {
    "suiteName": "tests",
    "outputDirectory": "./generated",
    "outputName": "./jest-report.xml",
    "classNameTemplate": "{classname}-{title}",
    "titleTemplate": "{classname}-{title}",
    "ancestorSeparator": " > ",
    "usePathForSuiteName": "true"
  },

thanks for the help

Upvotes: 29

Views: 36286

Answers (4)

snowe
snowe

Reputation: 1375

You can use the mocked function that is built into jest.

https://jestjs.io/docs/mock-function-api/#jestmockedsource-options

From the docs:

song.ts
export const song = {
  one: {
    more: {
      time: (t: number) => {
        return t;
      },
    },
  },
};
song.test.ts
import {expect, jest, test} from '@jest/globals';
import {song} from './song';

jest.mock('./song');
jest.spyOn(console, 'log');

const mockedSong = jest.mocked(song);
// or through `jest.Mocked<Source>`
// const mockedSong = song as jest.Mocked<typeof song>;

test('deep method is typed correctly', () => {
  mockedSong.one.more.time.mockReturnValue(12);

  expect(mockedSong.one.more.time(10)).toBe(12);
  expect(mockedSong.one.more.time.mock.calls).toHaveLength(1);
});

test('direct usage', () => {
  jest.mocked(console.log).mockImplementation(() => {
    return;
  });

  console.log('one more time');

  expect(jest.mocked(console.log).mock.calls).toHaveLength(1);
});

Upvotes: 3

Juan Franco
Juan Franco

Reputation: 309

Just in case you arrive here with the same error but in a slightly different scenario.

I'm upgrading from Jest v28 to v29 and I had a test with this:

jest.mock('../../../utils/http-client');
const mockHttpClient = jest.mocked(httpClient, true);

After the upgrade I've got an error like this:

Argument of type 'boolean' is not assignable to parameter of type '{ shallow: true; }'.ts(2769)

So I changed to:

const mockHttpClient = jest.mocked(httpClient, shallow: true);

Then I got the same error than the one posted by the OP here:

describe('custom-config-api test suite', () => {
  beforeEach(() => {
    mockHttpClient.get.mockResolvedValue({ data: { results: [] } });
  });

And solved it by setting shallow to false instead of true. The answer by J-Cint also worked, but I think this one is cleaner in my case.

Hope it helps!

Upvotes: 1

Lin Du
Lin Du

Reputation: 102207

Two ways to fix the TS types issue of the mock object.

  1. Use jest.MockedFunction
import axios from 'axios';
jest.mock('axios');

// ok
(axios.get as jest.MockedFunction<typeof axios.get>).mockResolvedValue({});

// Better
const mAxiosGet = jest.MockedFunction<typeof axios.get> = axios.get;
mAxiosGet.mockResolvedValue({});
  1. mocked helper function of ts-jest.
import axios from 'axios';
import { mocked } from 'ts-jest/utils';

jest.mock('axios');
const mAxiosGet = mocked(axios.get);

expect(jest.isMockFunction(mAxiosGet)).toBeTruthy();
mAxiosGet.mockResolvedValueOnce({});

Upvotes: 8

J-Cint
J-Cint

Reputation: 961

Casting the Axios function as a mock did the trick for me. So changing your mock to

(axios.get as jest.Mock).mockResolvedValue(resp);

Should make it work.

Upvotes: 58

Related Questions