How do I mock node-fetch with jest for a typescript project?

125 views Asked by At

I found this blogpost by Chris Armstrong: https://dev.to/chrisarmstrong/testing-node-fetch-with-jest-in-typescript-13oo

And it has gotten me much closer to an actually working script than any other sources I've found, however when following his steps and using his exact file in a barebones environment, I'm getting this compile-time error on lines 30 and 59

error TS2339: Property 'toHaveFetched' does not exist on type 'JestMatchers<FetchMockStatic>'.

Does anyone know how to get this working? I've spent about 3x as much time trying to mock fetch than it took me to write the code I'm writing unit tests for and would like to move on with the project I'm working on.

I created a barebones environment with the following file structure:

parent_folder
    /build
        /node_modules
        package.json
        package-lock.json
    /src
        /__tests__
            do_stuff_spec.ts
    tsconfig.json

Before running the following command:

npm i -D typescript node-fetch jest fetch-mock jest-fetch-mock @types/jest @types/fetch-mock @types/node-fetch

And here is my package.json file

{
  "devDependencies": {
    "@types/fetch-mock": "^7.3.8",
    "@types/jest": "^29.5.11",
    "@types/node-fetch": "^2.6.9",
    "fetch-mock": "^9.11.0",
    "jest": "^29.7.0",
    "jest-fetch-mock": "^3.0.3",
    "node-fetch": "^3.3.2",
    "typescript": "^5.3.3"
  },
  "scripts": {
    "build": "tsc",
    "test": "jest"
  }
}

And here is my tsconfig.json file

{
  "include": ["src"],
  "exclude": ["build"],
  "compilerOptions": {
    /* Language and Environment */
    "target": "ES2016",                               /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */

    "outDir": "./build",

    "baseUrl": "./",
    "paths": {
      "*": ["./node_modules/*", "*"]
    },

    "typeRoots": ["./build/node_modules/@types", "./build/"],
    "types": [
      "node",
      "jest"
    ],

    "lib": ["esnext"],

    /* Modules */
    "module": "commonjs",                                /* Specify what module code is generated. */

    /* JavaScript Support */
    "allowJs": true,                                  /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */
    // "checkJs": true,                                  /* Enable error reporting in type-checked JavaScript files. */

    /* Interop Constraints */
    "esModuleInterop": true,                             /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */
    "forceConsistentCasingInFileNames": true,            /* Ensure that casing is correct in imports. */
    "moduleResolution": "node",

    /* Type Checking */
    "strict": true,                                      /* Enable all strict type-checking options. */
  }
}

Basically, when you run 'npm run build' from the /build folder it compiles the files in /src and puts the output in build. This structure has worked for me for the rest of the project until this point, however mocking fetch is giving me a lot of trouble.

Edit: If I comment out the lines that are giving me problems (I.E. the lines like expect(fetchMock).toHaveFetched({...) I get a new error at runtime instead of compile-time where it says that TypeError: require(...).sandbox is not a function so I can't even do a workaround by using different methods of verifying that the result of the mocked fetch is correct.

0

There are 0 answers