当前位置: 首页 > 知识库问答 >
问题:

promise返回后Sinon存根未调用

颜君浩
2023-03-14

我试图用Mocha、Chai和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: '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
    })
  })
});

我可以用Sinon存根User.findOne()方法,但是当我尝试存根emailLogger.log()方法时,我遇到了麻烦。它似乎调用了存根,而不是真正的方法,而是期望(emailLogger.log)。to.have.been.called一旦返回false。

我尝试添加do()和一个假计时器以防出现延迟问题,以及一系列其他事情,但到目前为止还没有运气。

共有2个答案

赵鸿畴
2023-03-14

您永远不会从sendToUser函数返回promise,这意味着无法知道它实际何时完成。当您以同步方式测试async函数时,这意味着您在代码中调用emailLogger.log之前询问它是否已被调用!

你需要回报promise,然后你就可以按照邓肯在回答中的建议去做。

谷梁子昂
2023-03-14

一个很好的技巧是从测试函数返回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; 
   });
 });

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

 类似资料:
  • 我在获取一个sinon存根以返回/解析另一个sinon存根时遇到问题。我正在使用西农、柴、柴和摩卡。 我正在按顺序执行许多异步任务,我想测试的代码看起来像这样: 我尝试为此创建存根的尝试如下所示: “saveit”方法在Terminal.prototype,这就是为什么我需要在那里存根它。当我尝试运行它时,我收到错误消息: 在线上: 但如果我在控制台中转储终端对象,它看起来很好,就像任何其他存根对

  • 我正在用sinon和ava做测试。我正在清除一些函数,并检查这些函数是否被调用。我检查了控制台,函数正在被调用。但是sinon返回的是notCalled(。称为假)。下面是这段代码。 }; });

  • 我尝试了一个虚拟模块,并存根,但不工作。 应用程序.js test.js 我尝试了以下建议:sinon stub不替换函数 但还是一样。它不能取代功能。

  • 问题内容: 如果从调用, 则会 收到消息 “套接字已连接” ,但未调用。我在这里想念什么? 问题答案: 在AngularJS中,承诺结果在$ digest周期内异步传播。因此,仅在进入$ digest循环时才调用在then()中注册的回调函数。 因此,当您的套接字连接时,我们处于摘要周期。 创建一个新的Promise,但是直到下一个摘要周期(永远不会到来的摘要周期)之前,它的结果才会传播(因为没有

  • 我需要为一个endpoint创建一个单元测试,这个endpoint将向某个API发出HTTP请求,并发送回包含HTTP请求结果的响应, 我使用请求promise链接在这里节点包,你可以看到下面的代码: 来自 预计正文(响应数据)是: 我使用摩卡、柴和西农来运行单元测试,你可以在下面看到上述功能的单元测试案例: 当我运行时,此集成测试总是失败,需要找出如何正确地存根。

  • 我有一个带有路由器的express应用程序,我想与Sinon一起测试。我无法成功模拟传递到请求处理程序的参数,希望能得到一些帮助。 这是我当前使用Mocha、Sinon、Chai的测试设置