Subburaj
Subburaj

Reputation: 5192

Jest + mockImplementation + Number of calls: 0

I am using Jest as testing module. Jest spy function is not called, it says Number of calls: 0.

a.test.js

 const request = require('request-promise');
    const moduleA = require('./a');
    test('Update function', async () => {
    const postSpy = jest.spyOn(request, 'post').mockImplementation((input) => input);
    await moduleA();
    expect(postSpy).toBeCalledWith({
    method: 'POST',
    uri:"fsdsfd",
    headers: {
     'content-type': 'application/json'
    },
    body: {
      A:A,
      B:B      
    },
    json: true 
});
    });

a.js

const request = require('request-promise');

module.exports = async () => {
  var options = {
    method: 'POST',
    uri: 'fsdsfd',
    headers: {
      'content-type': 'application/json',
    },
    body: {
      A: A,
      B: B,
    },
    json: true,
  };

  try {
    const selectResult = await request(options);
    return selectResult;
  } catch (err) {
    return err;
  }
};

It throws error as expect(jest.fn()).toBeCalledWith(...expected) and Number of calls: 0. I think the mocked function is not called. I searched a lot regarding this but no hope. Any ideas??

EDIT

My Guess is that there is no method post in request-promise.

EDIT FOR REQUEST>POST()

    request.post({
      uri: 'fsdsfd',
      headers: {
        'content-type': 'application/json',
      },
      body: {
      A: A,
     B: B,
    },
    json: true,
    }, function(err, resp){
      if(err){
        console.log(err)
      } else {
        console.log(resp);
        return(resp)--------------->
      }
    });

ASYNC AWAIT EDIT

const ss = await request.post({
          uri: 'fsdsfd',
          headers: {
            'content-type': 'application/json',
          },
          body: {
          A: A,
         B: B,
        },
        json: true,
        });
return ss;

Here if you use this the arrow (-->) is not getting called so its not assign in test file so I can't check for result values.

Upvotes: 2

Views: 19484

Answers (1)

Lin Du
Lin Du

Reputation: 102257

You use request(...) instead of using request.post(...), so you need mock request function not request.post method.

E.g. a.js:

const request = require('request-promise');

module.exports = async () => {
  var options = {
    uri: 'fsdsfd',
    headers: {
      'content-type': 'application/json',
    },
    body: {
      A: 'A',
      B: 'B',
    },
    json: true,
  };

  try {
    const selectResult = await request.post(options);
    return selectResult;
  } catch (err) {
    return err;
  }
};

a.test.js:

const request = require('request-promise');
const moduleA = require('./a');

jest.mock('request-promise', () => {
  return {
    post: jest.fn(),
  };
});

describe('59261385', () => {
  afterEach(() => {
    jest.resetAllMocks();
  });
  test('Update function', async () => {
    request.post.mockResolvedValueOnce({ result: [] });
    const actual = await moduleA();
    expect(actual).toEqual({ result: [] });
    expect(request.post).toBeCalledWith({
      uri: 'fsdsfd',
      headers: {
        'content-type': 'application/json',
      },
      body: {
        A: 'A',
        B: 'B',
      },
      json: true,
    });
  });
});

Unit test result with coverage report:

 PASS  src/stackoverflow/59261385/a.test.js (11.669s)
  59261385
    ✓ Update function (33ms)

----------|----------|----------|----------|----------|-------------------|
File      |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
----------|----------|----------|----------|----------|-------------------|
All files |     87.5 |      100 |      100 |    83.33 |                   |
 a.js     |     87.5 |      100 |      100 |    83.33 |                20 |
----------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        13.599s

Source code: https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/59261385

Update:

You can use jest.spyOn too.

a.test.js:

const request = require('request-promise');
const moduleA = require('../a');

describe('59261385', () => {
  afterEach(() => {
    jest.restoreAllMocks();
  });
  test('Update function', async () => {
    const postSpy = jest.spyOn(request, 'post').mockResolvedValueOnce({ result: [] });
    const actual = await moduleA();
    expect(actual).toEqual({ result: [] });
    expect(postSpy).toBeCalledWith({
      uri: 'fsdsfd',
      headers: {
        'content-type': 'application/json'
      },
      body: {
        A: 'A',
        B: 'B'
      },
      json: true
    });
  });
});

codesandbox: https://codesandbox.io/s/jestjs-jgye4

Upvotes: 5

Related Questions