【问题标题】:Testing Mailgun .send() method with Mocha and Sinon使用 Mocha 和 Sinon 测试 Mailgun .send() 方法
【发布时间】:2017-02-24 21:34:39
【问题描述】:

我正在尝试为通过 ping Mailgun API 发送电子邮件的快速中间件函数编写单元测试。

module.exports = {
  sendEmail: function (req, res) {
    let reqBody = req.body;
    let to = reqBody.to;
    let from = reqBody.from;
    let subject = reqBody.subject;
    let emailBody = reqBody.body;

    let data = {
      from: from,
      to: to,
      subject: subject,
      text: emailBody
    };

    mailgun.messages().send(data, function (error, body) {
      if (error) {
        res.status(400).json(error);
        return;
      }
      res.status(200).json(body);
    });
  }
};

测试文件:

  describe('\'sendEmail\' method', () => {
    let mailgun;
    beforeEach(() => {
      mailgun = require('mailgun-js')({ apiKey: MAIL_GUN_API_KEY, domain: MAIL_GUN_DOMAIN });
    });

    it.only('should send the data to the MailGun API', (done) => {    
      sinon.spy(mailgun, 'messages');
      sinon.spy(mailgun.messages(), 'send');

      emailMiddleware.sendEmail(request, response);
      // using sinon-chai here
      mailgun.messages().send.should.have.been.called();
      done();    
    });

运行npm test时的结果:

TypeError: [Function] is not a spy or a call to a spy!
  1. 如何测试.send方法是否在mailgun.messages().send(...)中被调用?

  2. 我直接使用 mailgun API。我怎样才能存根 mailgun 本身?

【问题讨论】:

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


    【解决方案1】:

    你必须存根mailgun-js你必须存根这个包,然后你可以检查你想要的回报

    因为你在使用回调,所以别忘了返回它

    const sandbox = sinon.sandbox.create();
    sandbox.stub(mailgun({ apiKey: 'foo', domain: 'bar' }).Mailgun.prototype, 'messages')
      .returns({
        send: (data, cb) => cb(),
      });
    
    // Your stuff...
    
    sandbox.restore();
    

    您可以使用sandbox.spy() 来检查您想要什么,行为与sinon.spy() Doc here 相同

    【讨论】:

      【解决方案2】:

      如何测试 .send 方法是否被调用 mailgun.messages().send(...)?

      您需要存根方法send,而不仅仅是监视它并使其像真正的方法一样工作。

      当我想存根 mailgun-js 模块时,我会这样做。

          // Mock sandbox
          sandbox = sinon.sandbox.create()
      
          mailgunSendSpy = sandbox.stub().yields(null, { bo: 'dy' })
          sandbox.stub(Mailgun({ apiKey: 'foo', domain: 'bar' }).Mailgun.prototype, 'messages').returns({
            send: mailgunSendSpy
          })
      

      yields 方法将参数 null{bo: 'dy'} 传递给它找到的第一个回调。

      我认为它也回答了你的其他问题。

      【讨论】:

        【解决方案3】:
        const stubs = {};
        //Make a stub for the send method.
        stubs.mailgunSendStub = sinon.stub(
          { send: () => new Promise((resolve) => resolve(null)) },
          'send'
        );
        stubs.mailgunMessagesStub = sinon
          .stub(mailgun({ apiKey: 'k', domain: 'd' }).Mailgun.prototype, 'messages')
          .returns({
            send: stubs.mailgunSendStub, //call it here.
          });
        
         //Now you can test the call counts and also the arguments passed to the send() method.
         expect(stubs.mailgunSendStub.callCount).toBe(1);
         expect(stubs.mailgunSendStub.args[0][0]).toStrictEqual(someData);
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2019-03-24
          • 2015-12-01
          • 2016-06-24
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多