mock post method npm request module with jest

Tags: , , , ,



I know that npm request module is now deprecated, but i want to mock a post http call with jest.

Here is my function

import { post } from 'request'; 

export functionToFetch(uriFetching) {

    return post(
        {
            url: uriFetching,
            headers: {},
            json,
        },

        (error, response, body) => {

            if (error) {
                console.log('error)
                // return specific code
            }
              // return success code

            
        }

}

And in try this in my test :

import { post } from 'request';
import {functionToFetch} from './example';

it('should do some specific handling on error', () => {
    const fakeURI = 'http://example.com'
    
    request.post = jest.fn().mockImplementation(() => Promise.resolve(new Response('test')));

    // on error
    expect(functionToFetch(fakeURI).toEqual(expected);
    // on success
    expect(functionToFetch(fakeURI).toEqual(expected2);

});

But it returns TypeError: Cannot set property ‘post’ of undefined

I want to mock that method to handle error and response to test methods inside them

Answer

Use jest.mock() and post.mockImplementation() will do this. You can get the actual callback function passed in post function in your test case. And execute it manually with mocked arguments.

E.g.

index.js:

import { post } from 'request';

export function functionToFetch(uriFetching) {
  const json = {};

  post({ url: uriFetching, headers: {}, json }, (error, response, body) => {
    if (error) {
      console.log(error);
    } else {
      console.log(response);
    }
  });
}

index.test.js:

import { functionToFetch } from '.';
import { post } from 'request';

jest.mock('request');

describe('67210149', () => {
  afterAll(() => {
    jest.resetAllMocks();
  });
  it('should do some specific handling on error', () => {
    const mError = new Error('network');
    post.mockImplementation((option, callback) => {
      callback(mError);
    });
    const logSpy = jest.spyOn(console, 'log');
    const fakeURI = 'http://example.com';
    functionToFetch(fakeURI);
    expect(logSpy).toBeCalledWith(mError);
    expect(post).toBeCalledWith({ url: 'http://example.com', headers: {}, json: {} }, expect.any(Function));
  });
});

unit test result:

 PASS  examples/67210149/index.test.js (7.274 s)
  67210149
    ✓ should do some specific handling on error (24 ms)

  console.log
    Error: network
        at Object.<anonymous> (/Users/dulin/workspace/github.com/mrdulin/jest-v26-codelab/examples/67210149/index.test.js:8:20)
        at Object.asyncJestTest (/Users/dulin/workspace/github.com/mrdulin/jest-v26-codelab/node_modules/jest-jasmine2/build/jasmineAsyncInstall.js:106:37)
        at /Users/dulin/workspace/github.com/mrdulin/jest-v26-codelab/node_modules/jest-jasmine2/build/queueRunner.js:45:12
        at new Promise (<anonymous>)
        at mapper (/Users/dulin/workspace/github.com/mrdulin/jest-v26-codelab/node_modules/jest-jasmine2/build/queueRunner.js:28:19)
        at /Users/dulin/workspace/github.com/mrdulin/jest-v26-codelab/node_modules/jest-jasmine2/build/queueRunner.js:75:41
        at processTicksAndRejections (internal/process/task_queues.js:93:5)

      at console.<anonymous> (node_modules/jest-environment-enzyme/node_modules/jest-mock/build/index.js:866:25)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        7.836 s, estimated 8 s


Source: stackoverflow