4
votes

I am trying to mock a method's service i export as a module from my test. This is something i use to do with "sinon", but i would like to use jest as much as possible.

This is a classic test, i have an "authentication" service and a "mailer" service.

The "authentication" service can register new users, and after each new registration, it ask the mailer service to send the new user a "welcome email".

So testing the register method of my authentication service, i would like to assert (and mock) the "send" method of the mailer service.

How to do that? Here is what i tried, but it calls the original mailer.send method:

// authentication.js

const mailer = require('./mailer');

class authentication {
  register() { // The method i am trying to test
    // ...

    mailer.send();
  }
}

const authentication = new Authentication();

module.exports = authentication;


// mailer.js

class Mailer {
  send() { // The method i am trying to mock
    // ...
  }
}

const mailer = new Mailer();

module.exports = mailer;


// authentication.test.js

const authentication = require('../../services/authentication');

describe('Service Authentication', () => {
  describe('register', () => {
    test('should send a welcome email', done => {
      co(function* () {
        try {
          jest.mock('../../services/mailer');
          const mailer = require('../../services/mailer');
          mailer.send = jest.fn( () => { // I would like this mock to be called in authentication.register()
            console.log('SEND MOCK CALLED !');
            return Promise.resolve();
          });

          yield authentication.register(knownUser);

          // expect();

          done();
        } catch(e) {
          done(e);
        }
      });
    });
  });
});
1

1 Answers

6
votes

First you have to mock the mailer module with a spy so you can later set. And you to let jest know about using a promise in your test, have a look at the docs for the two ways to do this.

const authentication = require('../../services/authentication');
const mailer = require('../../services/mailer');
jest.mock('../../services/mailer', () => ({send: jest.fn()})); 

describe('Service Authentication', () => {
  describe('register', () => {
    test('should send a welcome email', async() => {
          const p = Promise.resolve()
          mailer.send.mockImplementation(() =>  p) 
          authentication.register(knownUser);
          await p
          expect(mailer.send).toHaveBeenCalled;
        }
      });
    });
  });
});