Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mocking / stubbing mongoose findById with sinon

I'm trying to stub my mongoose model, specifically the findById method of mongoose

I'm trying to make mongoose return the specified data, when findById is called with 'abc123'

Here's what I have so far:

require('../../model/account');

sinon = require('sinon'),
mongoose = require('mongoose'),
accountStub = sinon.stub(mongoose.model('Account').prototype, 'findById');
controller = require('../../controllers/account');

describe('Account Controller', function() {

    beforeEach(function(){
        accountStub.withArgs('abc123')
            .returns({'_id': 'abc123', 'name': 'Account Name'});
    });

    describe('account id supplied in querystring', function(){
        it('should retrieve acconunt and return to view', function(){
            var req = {query: {accountId: 'abc123'}};
            var res = {render: function(){}};

            controller.index(req, res);
                //asserts would go here
            });
    });

My problem is that I am getting the following exception when running mocha

TypeError: Attempted to wrap undefined property findById as function

What am I doing wrong?

like image 783
Alex Avatar asked Mar 01 '14 11:03

Alex


People also ask

What does findById return mongoose?

Return value findById returns the document where the _id field matches the specified id . If the document is not found, the function returns null .

What is findById in mongoose?

Mongoose | findById() Function The findById() function is used to find a single document by its _id field. The _id field is cast based on the Schema before sending the command. Installation of mongoose module: You can visit the link Install mongoose module. You can install this package by using this command.

What is Sinon stub ()?

The sinon. stub() substitutes the real function and returns a stub object that you can configure using methods like callsFake() . Stubs also have a callCount property that tells you how many times the stub was called.

How do you mock a variable in Sinon?

var sinon = require('sinon'); var start_end = require('./start_end'); describe("start_end", function(){ before(function () { cb_spy = sinon. spy(); }); afterEach(function () { cb_spy. reset(); }); it("start_pool()", function(done){ // how to make timer variable < 1, so that if(timer < 1) will meet start_end.


2 Answers

Take a look to sinon-mongoose. You can expects chained methods with just a few lines:

// If you are using callbacks, use yields so your callback will be called
sinon.mock(YourModel)
  .expects('findById').withArgs('abc123')
  .chain('exec')
  .yields(someError, someResult);

// If you are using Promises, use 'resolves' (using sinon-as-promised npm) 
sinon.mock(YourModel)
  .expects('findById').withArgs('abc123')
  .chain('exec')
  .resolves(someResult);

You can find working examples on the repo.

Also, a recommendation: use mock method instead of stub, that will check the method really exists.

like image 88
Gon Avatar answered Oct 16 '22 15:10

Gon


Since it seems you are testing a single class, I'd roll with the generic

var mongoose = require('mongoose');
var accountStub = sinon.stub(mongoose.Model, 'findById');

This will stub any calls to Model.findById patched by mongoose.

like image 21
Gaston Avatar answered Oct 16 '22 13:10

Gaston