【问题标题】:Make test using sinon stub for function using Promises使用 sinon stub 对使用 Promises 的函数进行测试
【发布时间】:2017-07-11 00:20:10
【问题描述】:

我想用 Sinon stub Promise 做一个测试用例

如果我没有从我的代码中解析,那么测试应该会失败,但目前它正在通过。

var sendMail = function (templateName, recipients, templateParameters, attachments, subject) {

return mailingExternalTemplateModel.findMailingTemplateId(templateName)
    .then( (result) => {
        var params = {
            "FromEmail": nodeMailjet.mailjetFromMail,
            "FromName": nodeMailjet.mailjetFromName,
            "Subject": subject,
            'MJ-TemplateID': result,
            'MJ-TemplateLanguage': true,
            "Recipients": recipients,
            "Vars": {
                'username': templateParameters.username,
                'hello': i18n.__('email.hello'),
                'voucher_details': i18n.__('email.voucher_details'),
                'email_footer': i18n.__('email.footer.i_love_my_price')
            }
        };

        if (attachments) {
            params.Attachments = attachments;
        }

        return mailjet
            .post("send")
            .request(params)
            .then((result) => {
                return result.body; //***** If i comment here then still test case goes green which should fail. so how i achive that?
            });
    })
    .catch( (err) => {
        return Promise.reject(err);
    });
};

如果我注释掉 return result.body;,这意味着 Promise 不会返回,测试应该会失败。但它没有发生。

测试用例:

var sinonStubPromise = require('sinon-stub-promise');
sinonStubPromise(sinon);

it('it should send mail successfully', function(done) {

    var findMailingTemplateIdStub = sinon.stub(mailingExternalTemplateModel, 'findMailingTemplateId');

    findMailingTemplateIdStub.returnsPromise().resolves(88888);

    var successResponse = {'successId': 989890};

    var request = sinon.stub().returnsPromise().resolves(successResponse);

    sinon.stub(mailjet, "post", function () {
        return {
            request: request
        }
    });

    mailSender.sendMail(templateName, recipients, templateParams, attachments, 'thats subject')
        .then((returnVal) => {
            assert.deepEqual(
                returnVal,
                successResponse
            );
        })
        .catch((err) => {

        })

    done();
});

【问题讨论】:

  • 为什么 - 投票?我不明白?这是一个完美的问题...
  • 尝试移动 done();在你的断言之后调用 then
  • @wietsevenema 它会给出错误错误:超过 2000 毫秒的超时。对于异步测试和钩子,确保调用“done()”;如果返回 Promise,请确保它已解决。
  • 如果你正在测试基于 Promise 的代码,不要使用 done,而是使用 Mocha 的 built-in promise support。此外,您的测试正在吞噬 assert.deepEqual() 由于空的 catch 处理程序引发的任何错误。
  • @robertklep 你能回答这个问题吗?提前致谢。

标签: javascript node.js promise mocha.js sinon


【解决方案1】:

如果不对您的代码进行广泛测试,我可以提供以下建议来解决您的问题:首先,Mocha supports promises,当您想要测试基于 Promise 的代码时,它比使用 done 效果更好。

此外,如果断言失败(引发错误),则永远不会处理该错误(它被“吞噬”),部分原因是您添加了一个空的.catch()。这无法通过在断言后添加done 来解决,因为它永远不会被调用(因为抛出了错误)。

尝试以下方法:

it('it should send mail successfully', function() {
  ...
  return mailSender.sendMail(templateName, recipients, templateParams, attachments, 'thats subject')
         .then((returnVal) => {
           assert.deepEqual(
             returnVal,
             successResponse
           );
         });
});

注意done 根本不再使用,而是将mailSender.sendMail 返回的承诺返回给 Mocha。

【讨论】:

  • 是的,这里不需要,但你能回答一下吗:如果我评论行返回result.body;那么我的测试应该失败。但目前测试通过了。
  • @ApoorvaShah 你能检查一下returnVal 是什么吗?如果你忽略了return result.body,我假设它是undefined
  • 这种风格也有点棘手。如果您忘记输入“return”,您的测试将始终为绿色。
  • @wietsevenema 如果您忘记了return,您很可能会得到UnhandledPromiseRejectionWarning。尽管如此,使用 Mocha 的内置 promise 断言比使用带有 done 的回调样式更不容易出错。
  • @robertklep returnVal 我得到 { "successId": 989890 } 主要是因为在测试用例中我写了 var successResponse = {'successId': 989890}; var request = sinon.stub().returnsPromise().resolves(successResponse);
【解决方案2】:

现在我将我的代码更改为以下和它的工作。

主要变化是

findMailingTemplateIdStub.returnsPromise().resolves(88888); change to
findMailingTemplateIdStub.returns(Promise.resolve(88888));

var request = sinon.stub().returnsPromise().resolves(successResponse);
changed to var request = sinon.stub().returns(Promise.resolve(successResponse));

   it('it should send mail successfully', function(done) {

    var findMailingTemplateIdStub = sinon.stub(mailingExternalTemplateModel, 'findMailingTemplateId');

    findMailingTemplateIdStub.returns(Promise.resolve(88888));

    var successResponse = {
        'body': {
                    Sent:
                    [
                      {
                          Email: 'test@example.com',
                          MessageID: '188589580585481212'
                      }
                    ]
                }
    };

    var request = sinon.stub().returns(Promise.resolve(successResponse));

    sinon.stub(mailjet, "post", function () {
        return {
            request: request
        }
    });

    mailSender.sendMail(templateName, recipients, templateParams, attachments, 'thats subject')
        .then((returnVal) => {
            assert.deepEqual(returnVal, successResponse.body);
            done();
        })
        .catch((err) => {
                done(err);
            }
        );
});

【讨论】:

    猜你喜欢
    • 2015-03-30
    • 2018-07-19
    • 2012-07-04
    • 2015-12-11
    • 2021-07-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多