2017-10-17 4 views
0

Mocha, Chai 및 Sinon을 사용하여 코드에 테스트를 추가하려고하지만이 두 번째 스텁 된 함수가 호출되는 것으로 인식되지 않는 이유를 이해하기 위해 애 쓰고 있습니다.약속 이후에 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; 
    }); 
}); 

이 (올바른 오류와) 약속이 어떤 이유로 실패 할 경우, 테스트가 실패 할 추가 혜택이있다.