Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Replace specific module in testing

I am testing my React-Redux app with Jest and as part of this in my API calls I am importing a fetch module cross-fetch. I want to override or replace this with fetch-mock. Here is my file structure:

Action.js

import fetch from 'cross-fetch';
export const apiCall = () => {
    return fetch('http://url');

Action.test.js

import fetchMock from 'fetch-mock';
import { apiCall } from './Action';
fetchMock.get('*', { hello: 'world' });
describe('actions', () => {
    apiCall().then(
        response => {
            console.log(response)
        })
})

Obviously at this point I haven't set up the test. Because cross-fetch is imported closer to the function it uses it's implementation of fetch, causing it to do the actual call instead of my mock. Whats the best way of getting the fetch to be mocked (apart from removing the import fetch from 'cross-fetch' line)?

Is there a way to do a conditional import depending on whether the node script called is test or build? Or set the mocked fetch to take priority?

like image 352
Sam Avatar asked Mar 02 '18 04:03

Sam


2 Answers

fetch-mock is not intended to replace the fetch() calls in the code you are testing nor do you need to change or remove any imports. Instead, it provides mock responses during your tests so that requests made with fetch() receive known, reliable responses.

like image 53
Code-Apprentice Avatar answered Nov 15 '22 12:11

Code-Apprentice


If your project is a webpack project, then https://github.com/plasticine/inject-loader is very useful. You can simply swap any dependency with a mock in just a few lines of code.

describe('MyModule', () => {
  let myModule;
  let dependencySpy;

  beforeEach(() => {
    dependencySpy= // {a mock/spy};
    myModule = require('inject-loader!./MyModule')({
      'cross-fetch': {dependencySpy},
    });
  });

  it('should call fetch', () => {
    myModule.function1();
    expect(dependencySpy.calls.length).toBe(1);
  });

});

Note: make sure you don't import the module under test at the top of your file. the require call does that part.

like image 30
Sylvain Avatar answered Nov 15 '22 14:11

Sylvain