Sravya Chebolu
Sravya Chebolu

Reputation: 31

How to mock the response of node-fetch in typescript using supertest and vitest

import { Router } from 'express'
import fetch from 'node-fetch'

const tasks = Router()

tasks.get('/middleware', async (req,res) => {
  const response = await fetch('https://dummy-api')
  res.json(response)
})

I am new to typescript and I am trying to write tests for the /middleware api. I am facing issues in mocking the fetch response. I am using supertest and vitest. Can someone help me with this?

Upvotes: 3

Views: 3035

Answers (1)

Keimeno
Keimeno

Reputation: 2659

You can mock node-fetch using vitest by writing the following in your test file:

import * as nodeFetch from "node-fetch";
import { Response } from "node-fetch";
import { vi, describe, it } from "vitest";
import app from '../path-to-your-express-app';
import request from "supertest"

vi.mock("node-fetch", async () => {
  const actual: typeof nodeFetch = await vi.importActual("node-fetch");

  return {
    ...actual,
    default: vi.fn()
  };
});
const fetch = vi.mocked(nodeFetch.default);

This allows you to overwrite the default export of node-fetch. What you are left with, is a mocked fetch function, that allows you to return anything you want.

For example, you can write the following in your test file:

describe(... () => {
  it(... () => {
    fetch.mockImplementationOnce(async () =>
      new Response('your response body')
    )

    // now you can send out the request using supertest
    // `fetch` won't send a request to `'https://dummy-api'`, 
    // but instead it will return the response of your `mockImplementationOnce` call
    const response = await request(app).get('/middleware');

    ...
  })
})

Upvotes: 3

Related Questions