简体   繁体   中英

Sinon - stubbing function with callback - causing test method to timeout

I have a method on a express route that looks like this:

exports.register_post = function(req, res) {
    var account = new Account();
    account.firstName = req.param('firstName');
        //etc...

    account.save(function(err, result) {

        email.sendOne('welcome', {}, function(err) {
            res.render('account/register', {
                title: 'Register'
            });
        });
    });
};

I've got a test, where I have email stubbed.

email is a module I require in the route.
It has a function like:

exports = module.exports.sendOne = function(templateName, locals, cb)

My test looks like this:

describe('POST /account/register', function(done) {

    var email;

    beforeEach(function(done) {
        accountToPost = {
            firstName: 'Alex',
        };

        email = require('../../app/helpers/email');
        sinon.stub(email)

        done();
    });

    afterEach(function(done) {
        email.sendOne.restore();
        done();
    })

    it('creates account', function(done) {
        request(app)
            .post('/account/register')
            .send(this.accountToPost)
            .expect(200)
            .end(function(err, res) {
                should.not.exist(err)
                //todo: asserts
                done();
            });
    });

    it('sends welcome email', function(done) {
        request(app)
            .post('/account/register')
            .send(this.accountToPost)
            .expect(200)
            .end(function(err, res) {
                should.not.exist(err)
                sinon.assert.calledWith(email.sendOne, 'welcome');
                done();
            });
    });
});

When I run the test, both fail, citing:

1) Controller.Account POST /account/register creates account: Error: timeout of 2000ms exceeded at null. (/usr/local/lib/node_modules/mocha/lib/runnable.js:165:14) at Timer.listOnTimeout [as ontimeout] (timers.js:110:15)

2) Controller.Account POST /account/register sends welcome email: Error: timeout of 2000ms exceeded at null. (/usr/local/lib/node_modules/mocha/lib/runnable.js:165:14) at Timer.listOnTimeout [as ontimeout] (timers.js:110:15)

If I comment out email.sendOne('welcome', {}, function(err) { in my route, then the first test (create account) passes.

Have I missed something when setting up my sinon stub?

Sinon stubs will not automatically fire any callback functions, you need to do this manually. It's actually really east to do though:

describe('POST /account/register', function(done) {

    var email;

    beforeEach(function(done) {
        accountToPost = {
            firstName: 'Alex',
        };

        email = require('../../app/helpers/email');
        sinon.stub(email);
        email.sendOne.callsArg(2);

        done();
    });

    afterEach(function(done) {
        email.sendOne.restore();
        done();
    })

    it('creates account', function(done) {
        request(app)
            .post('/account/register')
            .send(this.accountToPost)
            .expect(200)
            .end(function(err, res) {
                should.not.exist(err)
                //todo: asserts
                done();
            });
    });

    it('sends welcome email', function(done) {
        request(app)
            .post('/account/register')
            .send(this.accountToPost)
            .expect(200)
            .end(function(err, res) {
                should.not.exist(err)
                sinon.assert.calledWith(email.sendOne, 'welcome');
                done();
            });
    });
});

Notice the specific line:

        email.sendOne.callsArg(2);

The Sinon Stubs API has some good documentation on callsArg, and also callsArgWith (which may be useful for you testing error scenarios)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM