在诺言归还后,没有召唤诗乃残存

时间:2017-10-17 22:11:58

标签: javascript node.js unit-testing mocha sinon

我正在尝试使用Mocha,Chai和Sinon为我的代码添加更多测试,但是我很难理解为什么第二个存根函数不被识别为被调用。

我有一个向用户发送电子邮件的功能(我稍后会测试电子邮件功能 - 现在我只想处理我控制的存根依赖关系)

reorderPopulation()
# do nothing
unorderPopulation()
# Error: could not find function "unorderPopulation"
Porteous96:::unorderPopulation()
# do nothing
# should not be found

测试文件:

// 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');
    }
  }
}

我可以使用Sinon存储User.findOne()方法,但是当我尝试存根emailLogger.log()方法时,我遇到了麻烦。它似乎调用存根而不是真正的方法,但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: 'testemail@eml.co' }; 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 }) }) }); 返回false。

我尝试添加expect(emailLogger.log).to.have.been.calledOnce和假计时器,以防出现延迟问题,以及其他一些事情,但到目前为止还没有运气。

2 个答案:

答案 0 :(得分:0)

一个很好的技巧是从测试函数返回promise,这会导致Mocha等到promise完成。以下是您的工作方式:

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; 
   });
 });

这有额外的好处,如果承诺因任何原因失败,测试将失败(带有正确的错误)。

答案 1 :(得分:0)

您永远不会从$.ajax({ type: 'GET', url: 'get-breaks', data: { t_date: $t_date, emp_id: $emp_id } success: function (data) { //append to table if(data.dateArray) { data.dateArray.forEach(function(item,index) { $("table#breaks-table").append(createTr(item)); }); } }, error: function (data) { } }); function createTr(item) { var tr = '<tr>' + '<td class="className">' + item.start_break + '</td>' + '<td>' + item.end_break + '</td>' + '<td>' + item.time_diff + '</td>' + '</tr>'; return tr; } 函数返回诺言,这意味着无法知道诺言何时真正完成。当您以同步方式测试sendToUser函数时,这意味着您正在询问是否在代码中调用{em> before 之前调用了async

您需要兑现诺言,然后您可以按照邓肯的回答去做。