skip to Main Content

Short Version:

I am writing a test case for my Vue component using vue-test-utils and jest.

I am trying to create a Response object in one of my test cases, but I keep getting error
ReferenceError: Response is not defined

Long Version

I am trying to mock an API response when a Vuex action is dispatched using jest.
I have created a Vuex action like this

let fakeAccountList = [
  {"id":"abcd","title":"Random Account 1"},
  {"id":"pqrs","title":"Random Account 2"}
]
actions = {
   getAccounts: jest.fn(()=>{

     return new Promise((resolve, reject)=>{
       resolve(mockResponse(200,'ok',fakeAccountList))
      })
    })
 }

The getAccounts action returns a Promise which resolves to a list of accounts. The mockResponse function is as shown:

mockResponse = (status, statusText, response) => {

  return new Response(response, {
    status: status,
    statusText: statusText,
    headers: {
      'Content-type': 'application/json'
    }
  });
};

When mockResponse is called, I get the error ReferenceError: Response is not defined

I found this very old issue:
https://github.com/facebook/jest/issues/930
The comments suggest that it was fixed,but, it is not working for me. I do not want to import extra libraries such as isomorphic-fetch just for this.

Here is my devDependencies in package.json:

"devDependencies": {
    "@vue/cli-plugin-babel": "3.0.3",
    "@vue/cli-plugin-e2e-cypress": "3.0.3",
    "@vue/cli-plugin-eslint": "3.0.3",
    "@vue/cli-plugin-unit-jest": "3.0.3",
    "@vue/cli-service": "3.0.3",
    "@vue/test-utils": "1.0.0-beta.25",
    "babel-core": "7.0.0-bridge.0",
    "babel-jest": "23.6.0",
    "less": "3.0.4",
    "less-loader": "4.1.0",
    "lodash": "4.17.10",
    "node-sass": "4.9.2",
    "sass-loader": "7.0.3",
    "vue-template-compiler": "2.5.16",
  }

Any help would be appreciated. Thanks in advance

2

Answers


  1. I am using a react application and just adding the below statement in your mock file resolved the issue. Hope this might be helpful for you or others.

    import 'isomorphic-fetch'

    Login or Signup to reply.
  2. isomorphic-fetch does not implement Response.error() . So I use whatwg-fetch

    Here’s a test that shows it working. I use fetch-mock-jest for the fetch mocking.

    /**
     * @jest-environment node
     */
    import 'whatwg-fetch';
    import fetchMock from 'fetch-mock-jest';
    describe('http', () => {
      let fetchConfigResponse: (new () => Response) | undefined;
      beforeEach(() => {
        fetchConfigResponse = fetchMock.config.Response;
        jest.useFakeTimers({ advanceTimers: true });
      });
      afterEach(() => {
        jest.useRealTimers();
        fetchMock.mockReset();
        fetchMock.config.Response = fetchConfigResponse;
      });
    
      it('Simple fetch example', async () => {
        jest.setSystemTime(new Date('2022-01-01T00:00:00Z'));
        fetchMock.mock('https://trajano.net', { body: { hello: 'world' } });
        const response = await fetch('https://trajano.net');
        expect(Date.now()).toBe(new Date('2022-01-01T00:00:00Z').getTime());
        expect(response.status).toBe(200);
        expect(await response.json()).toStrictEqual({ hello: 'world' });
      });
      it('Non-JSON json() call', async () => {
        jest.setSystemTime(new Date('2022-01-01T00:00:00Z'));
        fetchMock.mock('https://trajano.net', { body: 'not a json' });
        const response = await fetch('https://trajano.net');
        expect(Date.now()).toBe(new Date('2022-01-01T00:00:00Z').getTime());
        expect(response.status).toBe(200);
        try {
          await response.json();
          fail('should not get here');
        } catch (e) {
          expect(e instanceof Error).toBeTruthy();
        }
      });
    
      it('Error example', async () => {
        jest.setSystemTime(new Date('2022-01-01T00:00:00Z'));
        fetchMock.mock('https://trajano.net/bad-request', {
          status: 400,
          body: { bad: 'request' },
        });
        const response = await fetch('https://trajano.net/bad-request');
        expect(Date.now()).toBe(new Date('2022-01-01T00:00:00Z').getTime());
        expect(response.status).toBe(400);
        expect(response.ok).toBe(false);
        expect(await response.json()).toStrictEqual({ bad: 'request' });
      });
    
      it('401 Error example', async () => {
        jest.setSystemTime(new Date('2022-01-01T00:00:00Z'));
        fetchMock.mock('https://trajano.net/bad-request', {
          status: 401,
          body: { bad: 'request' },
        });
        const response = await fetch('https://trajano.net/bad-request');
        expect(Date.now()).toBe(new Date('2022-01-01T00:00:00Z').getTime());
        expect(response.status).toBe(401);
        expect(response.ok).toBe(false);
        expect(await response.json()).toStrictEqual({ bad: 'request' });
      });
    
      it('should work with Response.error()', async () => {
        fetchMock.config.Response = Response;
        fetchMock.mock('https://trajano.net/bad-request', Response.error());
        const response = await fetch('https://trajano.net/bad-request');
        expect(response.status).toBe(0);
      });
      it('should work with global.Response.error()', async () => {
        fetchMock.config.Response = global.Response;
        fetchMock.mock('https://trajano.net/bad-request', global.Response.error());
        const response = await fetch('https://trajano.net/bad-request');
        expect(response.status).toBe(0);
      });
      it('Response.error type check', async () => {
        fetchMock.config.Response = Response;
        expect(Response.error() instanceof Response).toBe(true);
        expect(
          fetchMock.config.Response?.prototype.isPrototypeOf(Response.error())
        ).toBe(true);
      });
    });
    

    Another approach but I don’t normally do so I have better control of the tests is to add it to jestConfig.setupFiles as

    require('whatwg-fetch');
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search