VtoCorleone
VtoCorleone

Reputation: 17203

Unit test mongoose promises with sinon

I am trying to unit test a mongoose object that uses promises. I have written the test below and it works but it's not complete. I can't figure out how to test if the 'then' or 'catch' methods are called.

How can I use a spy to check that the 'then' method is called when I resolve the promise?

Method to test

export function create(req, res) {
  User
    .createAsync(req.body)
    .then(handleCreate(res, req.originalUrl))
    .catch(handleError(res));
}

Unit test

it('should do something', () => {
  const req = {
    body: 45,
  };

  const res = {};

  const mockRole = sandbox.mock(Role).expects('createAsync').once().withArgs(45)
    .returns(Promise.resolve());

  controller.create(req, res);
});

UPDATE WITH SOLUTION I USED (May 6th, 2016)

Thanks @ReedD for helping me in the right direction

Although this "works", I feel like I'm testing the functionality of promises more than my code.

it('should call create with args and resolve the promise', () => {
  const createSpy = sinon.spy();
  const errorSpy = sinon.spy();

  sandbox.stub(responses, 'responseForCreate').returns(createSpy);
  sandbox.stub(responses, 'handleError').returns(errorSpy);

  sandbox.mock(Role).expects('createAsync').once().withArgs(45)
    .returns(Promise.resolve());

  return controller.create(req, res).then(() => {
    expect(createSpy.calledOnce).to.be.equal(true);
    expect(errorSpy.calledOnce).to.be.equal(false);
  });
});

Upvotes: 0

Views: 592

Answers (1)

ReedD
ReedD

Reputation: 997

You could add handleCreate and handleError to module.exports and then make stubs or spys of those. Below is an example of what I think you're trying to do. I also assumed you were using sinon/chai.

http://ricostacruz.com/cheatsheets/sinon-chai.html

// controller.js

module.exports = {
    handleCreate: function () {
        // ..code
    },
    handleError: function () {
        // ..code
    },
    create: function (req, res) {
        User
            .createAsync(req.body)
            .then(this.handleCreate(res, req.originalUrl))
            .catch(this.handleError(res));
    }
};



// test/test.js

var controller = require('../controller');

it('should do something', function (done) {

    var handleCreate = sandbox.spy(controller, 'handleCreate');
    var handleError  = sandbox.spy(controller, 'handleError');
    var mockRole     = sandbox
        .mock(Role)
        .expects('createAsync')
        .once().withArgs(45)
        .returns(Promise.resolve());


    var req = {
        body: 45,
    };

    var res = {
        send: function () {
            expect(handleCreate).to.be.calledOnce;
            expect(handleError).to.not.be.called;
            done();
        }
    };

    controller.create(req, res);
});

Upvotes: 1

Related Questions