ChaseHardin
ChaseHardin

Reputation: 2269

Trigger mocked callback argument with Jest

Using Jest, I'd like to trigger the configure callback argument. If I were to write this with a sinon stub, I could do something like configure.yields('my value'). Does Jest have anything similar? To help illustrate what I'm after, I created a simple example.

I've imported mymodule, instantiated, and called the configure function. I'd like my test to trigger this callback. i.e. (err, results) => ...

import MyModule from 'mymodule';

export function execute(key, value) {
  return new Promise((resolve, reject) => {
      new MyModule().configure(key, value, (err, result) => {
          // I need my test to trigger this section of code...
          return resolve('my resolved value')
      })
  })
}

This test is mocking MyModule and setting configure to a jest.fn(). While I have everything mocked, I'm not able to specify the configure args and trigger a specific argument. Ideally, I'd like to do something like mockFn.yields('my value') to trigger the configure callback.

import MyModule from 'mymodule';

jest.mock('mymodule');
describe('Test Example', () => {
  test('should trigger mocked args callback', async () => {
      const mockFn = jest.fn();
      const key = 'my_key';
      const value = 'my_value';

      const actual = require('./src/my-service');

      MyModule.mockImplementation(() => {
        return {
            configure: mockFn
        };
      });

      await actual.execute(key, value)

      // how can I trigger the mocked configure argument callback?
  });
});

Test currently fails because it cannot trigger the callback function. Error states: Async callback was not invoked

Upvotes: 2

Views: 835

Answers (1)

Estus Flask
Estus Flask

Reputation: 222474

The error means that a promise that test async function returns wasn't settled. This happens because execute returns a pending promise, mocked configure doesn't call a callback that is supposed to resolve it.

configure should be mocked correctly and behave the same way as original implementation regarding callback argument:

mockFn.mockImplementation((key, value, cb) => cb(null, 'some result'));
const promise = actual.execute(key, value);
expect(mockFn).toBeCalledWith(key, value, expect.any(Function));
await expect(promise).resolves.toBe('my resolved value');

Upvotes: 1

Related Questions