xolvio / rtd

DEPRECATED: The Test Runner for Meteor
164 stars 37 forks source link

How to mock the event object #151

Closed adamdawkins closed 10 years ago

adamdawkins commented 10 years ago

On a click event on a link, I call e.preventDefault()

Template.user_loggedIn.events({
  'click #logout': function (e, tmpl) {
    Meteor.logout(function (err) {
      if (err) {
        // show error message
      } else {
        // show message that says logged out
      }
    });
    e.preventDefault();
  }
});

When I call Template.user_loggedIn.fireEvent('click #logout') in my Unit Test, I get:

PhantomJS 1.9.7 (Mac OS X) Template.user_loggedIn 'click #logout' event calls Meteor.logout FAILED
    TypeError: 'undefined' is not an object (evaluating 'e.preventDefault')

How do I mock, stub, or otherwise define e to get around this? This feels like something that should be possible.

Thanks for your help in advance.

samhatoum commented 10 years ago

RTDs fireEvent is your friend :)

http://xolv.io/blog/2013/04/testing-form-submissions-in-meteor

https://github.com/xolvio/rtd/blob/master/lib/meteor-stubs.js#L141

EDIT: I'm sorry, I mis understood your question... thinking...

samhatoum commented 10 years ago

Try:

Template.user_loggedIn.fireEvent('click #logout', eMock), where eMock would be a mock object that you would spyon

adamdawkins commented 10 years ago

You nailed it.

Here's the working test:

    describe("Template.user_loggedIn 'click #logout' event", function () {
        it("prevents the default event action", function () {
           var e = jasmine.createSpyObj('e', ['preventDefault']);
           Template.user_loggedIn.fireEvent('click #logout', e);
           expect(e.preventDefault).toHaveBeenCalled();
       });

       it("calls Meteor.logout", function () {
           var e = jasmine.createSpyObj('e', ['preventDefault']);
           spyOn(Meteor, 'logout');
           Template.user_loggedIn.fireEvent('click #logout', e);
           expect(Meteor.logout).toHaveBeenCalled();
       });
    });

And, for completeness, incase somebody's Googling, the implementation:

Template.user_loggedIn.events({
  'click #logout': function (e, tmpl) {
    Meteor.logout(function (err) {
      if (err) {
        // show error message
      } else {
        // show message that says logged out
      }
    });

    e.preventDefault();
  }
});

Thanks for your help.