Apoorva Shah
Apoorva Shah

Reputation: 632

Make test using sinon stub for function using Promises

I want to make a Test Case using Sinon stub Promise

If i am not resolving from my code then test should fail but currently it is passing.

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

If I comment out return result.body;, which mean the Promise don't return, the test should fail. But it is not happening.

Test case:

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

Upvotes: 0

Views: 1311

Answers (2)

Apoorva Shah
Apoorva Shah

Reputation: 632

Now i changed my code to following and its working.

major change is

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

and

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: '[email protected]',
                          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);
            }
        );
});

Upvotes: 1

robertklep
robertklep

Reputation: 203231

Without testing with your code extensively, I can offer the following advise that might solve your problem: firstly, Mocha supports promises, which works much better when you want to test promises-based code than using done.

Also, if the assertion fails (which throws an error), the error is never handled (it's "swallowed"), partly because you added an empty .catch(). This can't be solved by adding done after the assertion, because it will never get called (because of the error being thrown).

Try the following:

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

Notice how done isn't used at all anymore, and instead the promise returned by mailSender.sendMail is returned to Mocha.

Upvotes: 1

Related Questions