Anutrix
Anutrix

Reputation: 273

How to mock a promisified and bound function?

I need to write a test for a function in jest. I have function like following:

async function fun(conn, input){
    const connection = conn.getConnection();
    ....
    // some output gets generated from input 
    // const processed_input = input???;
    ....
    const x = util.promisify(connection.query).bind(connection);
    return /* await */ x(processed_input);
}

I want to expect the value of processed_input that is passed to function x.

I thought that something like .toHaveBeenCalledWith should work but I am not sure how it works for promisified bound functions.

I also tried to mock query doing something like conn.getConnection = { query: jest.fn() } before the fun call but I'm not sure how to move forward to expect it.

So far my current solution is to have Jest expect statements inside query function.

conn.getConnection = {
 query: function(processed_input){ //expect processed_input to be; } 
}`

Hoping for a better way.

Upvotes: 5

Views: 2287

Answers (1)

Lin Du
Lin Du

Reputation: 102527

connection.query is a Nodejs error-first callback, you need to mock the implementation of it and invoke the error-first callback manually with mocked error or data.

Unless you need bind context, you don’t need it. From your question, I don’t see the need for bind context.

E.g.

func.js:

const util = require('util');

async function fun(conn, input) {
  const connection = conn.getConnection();
  const processed_input = 'processed ' + input;
  const x = util.promisify(connection.query).bind(connection);
  return x(processed_input);
}

module.exports = fun;

func.test.js:

const fun = require('./func');

describe('67774122', () => {
  it('should pass', async () => {
    const mConnection = {
      query: jest.fn().mockImplementation((input, callback) => {
        callback(null, 'mocked query result');
      }),
    };
    const mConn = {
      getConnection: jest.fn().mockReturnValueOnce(mConnection),
    };
    const actual = await fun(mConn, 'input');
    expect(actual).toEqual('mocked query result');
    expect(mConn.getConnection).toBeCalledTimes(1);
    expect(mConnection.query).toBeCalledWith('processed input', expect.any(Function));
  });
});

test result:

 PASS  examples/67774122/func.test.js (7.015 s)
  67774122
    ✓ should pass (4 ms)

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

Upvotes: 8

Related Questions