Meteor / Jasmine / Velocity:如何测试需要登录用户的服务器方法?

时间:2015-03-01 17:19:56

标签: meteor meteor-velocity meteor-jasmine

使用velocity / jasmine,我对如何测试需要当前登录用户的服务器端方法有点困惑。有没有办法让Meteor认为用户是通过stub / fake登录的?

myServerSideModel.doThisServerSideThing = function(){
    var user = Meteor.user();
    if(!user) throw new Meteor.Error('403', 'not-autorized');
}

Jasmine.onTest(function () {
    describe("doThisServerSideThing", function(){
        it('should only work if user is logged in', function(){
            // this only works on the client :(
            Meteor.loginWithPassword('user','pwd', function(err){
                expect(err).toBeUndefined();

            });
        });
    });
});

4 个答案:

答案 0 :(得分:5)

您可以做的是将用户添加到您的测试套件中。您可以通过在服务器端测试脚本中填充这些用户来执行此操作:

类似的东西:

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

然后,一个好的策略可能是在您的测试中使用beforeAll来登录(这是客户端方面):

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

这是假设您的测试尚未登录。您可以通过检查Meteor.user()并正确登出afterAll等来更加体现这一点。请注意,您可以轻松地将done回调传递给许多Accounts功能

基本上,您不必模拟用户。只需确保在Velocity / Jasmine DB中有合适的用户和正确的角色。

答案 1 :(得分:5)

假设你有一个像这样的服务器端方法:

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

在执行方法之前,您不需要制作Meteor.loginWithPassword。您所要做的就是通过更改方法函数调用的this.userId上下文来存根this

Meteor.methodMap对象上提供了所有已定义的流星方法。因此,只需使用不同的this上下文

调用该函数
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');
    });

});

编辑:此解决方案仅在Meteor< = 1.0.x

上测试

答案 2 :(得分:1)

您在测试什么?为什么要求用户登录?我拥有的大多数方法需要一个用户对象,我将用户对象传递给。这允许我在没有实际登录的情况下从测试中调用。所以在实际运行代码时我会通过...

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

但是从测试开始,我会称之为......

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

答案 3 :(得分:1)

我认为Meteor.server.method_handlers["nameOfMyMethod"]允许你调用/应用Meteor方法并提供this作为第一个参数,至少在当前版本中是什么(1.3.3)

this.userId = userId;
Meteor.server.method_handlers["cart/addToCart"].apply(this, arguments);