Meteor / Jasmine / Velocity : how to test a server method requiring logged in user?

我们两清 提交于 2019-12-03 12:54:32

What you could do is add users just to your test suite. You could do this by populating these users in a the server-side test script:

Something like:

Jasmine.onTest(function () {
  Meteor.startup(function() {
    if (!Meteor.users.findOne({username:'test-user'})) {
       Accounts.createUser
          username: 'test-user'
  ... etc

Then, a good strategy could be to use the beforeAll in your test to login (this is client side):

Jasmine.onTest(function() {
  beforeAll(function(done) {
    Meteor.loginWithPassword('test-user','pwd', done);
  }
}

This is assuming your test isn't logged in yet. You can make this more fancy by checking for Meteor.user() and properly logging out in an afterAll, etc. Note how you can handily pass the done callback to many of the Accounts functions.

Essentially, you don't have to mock a user. Just make sure you have the right users, with the correct roles, available in the Velocity/Jasmine DB.

Lets say you have a server side method like this:

Meteor.methods({
    serverMethod: function(){
        // check if user logged in
        if(!this.userId) throw new Meteor.Error('not-authenticated', 'You must be logged in to do this!')

       // more stuff if user is logged in... 
       // ....
       return 'some result';
    }
});

You do not need to make a Meteor.loginWithPassword before executing the method. All you got to do is stub the this.userId by changing the this context of the method function call.

All defined meteor methods are available on the Meteor.methodMap object. So just call the function with a different this context

describe('Method: serverMethod', function(){
    it('should error if not authenticated', function(){
         var thisContext = {userId: null};
         expect(Meteor.methodMap.serverMethod.call(thisContext).toThrow();
    });

    it('should return a result if authenticated', function(){
         var thisContext = {userId: 1};
         var result = Meteor.methodMap.serverMethod.call(thisContext);
         expect(result).toEqual('some result');
    });

});

EDIT: This solution was only tested on Meteor <= 1.0.x

What are you testing and why does it require a user to be logged in? Most of the methods I have that need a user object I pass the user object into. This allows me to call from a test without actually being logged in. So in the actual running of the code I would pass...

var r = myMethod(Meteor.user());

but when running from the test I would call like...

it('should be truthy', function () {
  var r = myMethod({_id: '1', username: 'testUser', ...});
  expect(r).toBeTruthy();
});

I think that Meteor.server.method_handlers["nameOfMyMethod"] allows you to call/apply a Meteor method and supply this as the first parameter at least in the current version (1.3.3)

this.userId = userId;
Meteor.server.method_handlers["cart/addToCart"].apply(this, arguments);
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!