使用Mocha和Sinon测试Mailgun的.send()方法

3
我正在尝试为一个使用Mailgun API发送电子邮件的express中间件函数编写单元测试。
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. 如何测试在mailgun.messages().send(...)中是否调用了.send方法?

  2. 我直接使用mailgun API。如何桩mock mailgun本身?

3个回答

5

你需要对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() 相同。详见此处文档

1

如何测试是否在mailgun.messages().send(...)中调用了.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
    })
方法将null{bo: 'dy'}参数传递给它找到的第一个回调函数。

我认为这也回答了你的另一个问题。


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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接