2017-10-17 10 views
0

私はMocha、Chai、Sinonのコードにさらにテストを追加しようとしていますが、なぜこの第2のスタブされた関数が呼び出されたとして認識されないのか分かりません。約束の後にSinonのスタブが返されない

は、私は、ユーザーに電子メールを送信する機能を持っている(私は後に電子メール機能をテストします - 今、私はちょうど私が制御依存関係スタブのハンドルを取得したいため)

// EmailSender.js 
const models = require('../models'); 
const User = models.user; 
const emailLogger = require('./emailLogger'); 

class EmailSender { 
    constructor(subject, emailData) { 
    this.subject = subject; 
    this.emailData = emailData; 
    } 

    sendToUser() { 
    let email = this.emailData.email; 

    User.findOne({ where: { $or: [ 
     { email: email }, 
     { workEmail: email }, 
    ] } }) 
    .then(function (userData) { 
     if (userData) { 
     emailLogger.log('Send to anon - sending to user ' + userData.id); 
     }); 
    } else { 
     emailLogger.log('Send to anon - no user found'); 
    } 
    } 
} 

そして、テストファイル:

const EmailSender = require('../../../helpers/emailSender'); 
const models = require('../../../models'); 
const User = models.user; 
const emailLogger = require('../../../helpers/emailLogger'); 
const chai = require("chai"); 
const sinon = require('sinon'); 
const sinonChai = require("sinon-chai"); 

const expect = chai.expect; 
chai.use(sinonChai); 

describe('The emailSender',() => { 
    let emailData; 

    beforeEach(() => { 
    emailData = { 
     email: '[email protected]' 
    }; 
    sinon.stub(User, 'findOne').returns(Promise.resolve()); 
    sinon.stub(emailLogger, 'log'); 
    }) 

    afterEach(() => { 
    User.findOne.restore(); 
    emailLogger.log.restore(); 
    }) 

    describe('sendToUser method',() => { 
    it('logs an email if a user is found',() => { 
     let emailSender = new EmailSender('Email subject', emailData); 
     emailSender.sendToUser(); 

     expect(User.findOne).to.have.been.calledOnce; // works 
     expect(emailLogger.log).to.have.been.calledOnce; // doesn't 
    }) 
    }) 
}); 

私はSinonでUser.findOne()メソッドをスタブすることができますが、私がしようとするとemailLogger.log()メソッドをスタブとき、私はトラブルに巻き込まれます。実際のメソッドではなく、スタブを呼び出すように見えますが、expect(emailLogger.log).to.have.been.calledOnceはfalseを返します。

私は遅延の問題があった場合に備えてdone()と偽のタイマーを追加しようとしましたが、それ以外にもさまざまなものがありましたが、これまで運がありませんでした。

答えて

0

大きなトリックは、約束が完了するまでモカを待たせるテスト機能から約束を返すことです。ここでは、あなたがこれを行うだろう方法は次のとおりです。

it('logs an email if a user is found',() => { 
    const emailSender = new EmailSender('Email subject', emailData); 
    return emailSender.sendToUser().then(() => { 
     //check after the sendToUser promise is complete, but before the test is done 
     expect(User.findOne).to.have.been.calledOnce; 
     expect(emailLogger.log).to.have.been.calledOnce; 
    }); 
}); 

これは約束が何らかの理由で失敗した場合、テストは(正しいエラーで)に失敗するという付加的な利点を持っています。

関連する問題