Jest with fetch-mock generating error: TypeError: Cannot read property 'prototype' of undefined when using on nodejs

Viewed 2823

I'm almost sure it's my mistake, but I spent one entire day trying to solve and I've being failed .

I'm trying to configure the fetch-mock on node to use with jest. I tried a lot of things and the best result that I have is this:

https://user-images.githubusercontent.com/824198/50566568-7b49e400-0d22-11e9-884f-89720899de3a.png

I'm sure my mock is working because if I pass it through parameter to the "Myclass.query" it works perfectly.

I'm also sure that the mock is arriving in my test file, because the mock function is present in the fetch module.

But... all together aren't working .

I created a very simple and small project to see this problem happening:

https://github.com/cesarjr/test-node-fetch

Can anyone help me?

2 Answers

Jest uses the mock at __mocks__/node-fetch.js any time node-fetch is required during the test.

The problem is that the first thing fetch-mock does is require node-fetch.

This means that Request is not defined when it is set on the config here, so calling prototype on the undefined Request causes an error here.

Someone smarter than me might know how to force Jest to require the actual node-fetch when fetch-mock requires node-fetch in the mock for node-fetch, but from what I can see it doesn't look like it is possible.


Looks like you will have to delete the mock at __mocks__/node-fetch.js and pass fetch to your code, something like this:

myclass.js

class MyClass {
  static query(fetch, sessionId, query) {
    const url = 'https://api.foobar.com';

    const body = {
      sessionId,
      query
    };

    return fetch(url, {
      method: 'post',
      body: JSON.stringify(body)
    })
      .then(res => res.json());
  }
}

module.exports = MyClass;

...then create the sandbox in your test and pass it to your code, something like this:

myclass.test.js

const fetch = require('fetch-mock').sandbox();
const MyClass = require('./myclass');

describe('MyClass', () => {
  describe('.query', () => {
    it('returns the response', () => {
      fetch.mock('*', {'result': {'fulfillment': {'speech': 'The answer'}}});

      expect.assertions(1);

      return MyClass.query(fetch, '123', 'the question').then((data) => {
        expect(data.result.fulfillment.speech).toBe('The answer');  // SUCCESS
      });
    });
  });
});
Related