Hello Everybody,
I’m trying to test Meteor Methods inside a packge with Jasmine.
I don’t find anywhere how to do it correctly
Please, help me
Hi I don’t know any guidelines how to test meteor methods but this is how I do it:
- basically all meteor methods in my apps are “stupid” and they perform only 2 things:
- they tests if all attributes are correct using meteor checks: http://docs.meteor.com/#/full/check
- they pass execution to dedicated service object which is responsible for handling all business logic
So testing is quite easy.
- check if method throws an error when wrong attributes are passed
- stub service object and check if execution is passed to it when correct attributes were given (service object can be tested in dedicated test suite)
Other things:
- To simplify everything I write tests for methods only on the server.
- Probably your meteor methods requires logged in user. To simulate this you can use setUserId: http://docs.meteor.com/#/full/method_setUserId in before filter.
Thanks man, it’s a good approach. I will use it, i guess
A nice approach. I’m wondering, though, from where exactly you invoke setUserId()
in order to simulate a logged in user. It seems to be callable from within a meteor method, and that’s it. How do you call it from outside the method and inside the tests?
You can also use the https://github.com/meteor-velocity/velocity-helpers package to isolate methods and easily test them
Thank you, @sam. I did a little looking in your Letterpress repo and came up with this nice example of how to do it using velocity-helpers:
describe('Accounts API', function() {
describe('isSubscribed', function() {
it('gets the currently signed in user and checks id they are subscribed', function() {
// SETUP
var aUser = {
a: 'user'
};
spyOn(Meteor.users, 'findOne').and.returnValue(aUser);
spyOn(Letterpress.Services.Account, 'isSubscribed');
// EXECUTE
getMethod('isSubscribed').apply({userId: 'myId'});
// VERIFY
expect(Meteor.users.findOne).toHaveBeenCalledWith('myId');
expect(Letterpress.Services.Account.isSubscribed).toHaveBeenCalledWith(aUser);
});
});
});
This is what I’ve been looking for.
Stubbing is great, but I would have to stub a lot of logic as we have wrapped most of it in meteor methods.
Is it not possible in Meteor to write package tests that don’t stub collections, but instead make use of Meteor.call(‘x’), where x mutates collections?
For the userId issue what I actually do is:
- Separate the business logic from the framework. Methods are just functions for me as you said.
- When I need to test the userId thing or something that’s part of
this
i just calll he function withapply
orcall
and pass a fake object representing just like:
myMethod.apply({ userId: 'fakeUserId'}, arguments);
Just seeing this as another argument.