Используя скорость / жасмин, я немного застрял в том, как я должен тестировать серверный метод, требующий, чтобы в данный момент был зарегистрирован пользователь. Есть ли способ заставить Meteor думать, что пользователь вошел в систему через заглушку / фальшивку?

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

            });
        });
    });
});
8
Petrov 1 Мар 2015 в 20:19

4 ответа

Лучший ответ

Что вы можете сделать, так это добавить пользователей только в свой набор тестов. Это можно сделать, указав этих пользователей в серверном сценарии тестирования:

Что-то типа:

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.

5
Thomas Goorden 3 Мар 2015 в 16:55

Я думаю, что Meteor.server.method_handlers["nameOfMyMethod"] позволяет вызывать / применять метод Meteor и указывать this в качестве первого параметра, по крайней мере, в текущей версии (1.3.3)

this.userId = userId;
Meteor.server.method_handlers["cart/addToCart"].apply(this, arguments);
1
zenWeasel 15 Июн 2016 в 04:28

Что вы тестируете и почему для этого требуется, чтобы пользователь вошел в систему? Большинству имеющихся у меня методов нужен объект пользователя, которому я передаю объект пользователя. Это позволяет мне звонить из теста без входа в систему. Таким образом, при фактическом выполнении кода я бы пропустил ...

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

Но при выходе из теста я бы позвонил как ...

it('should be truthy', function () {
  var r = myMethod({_id: '1', username: 'testUser', ...});
  expect(r).toBeTruthy();
});
1
pstuart2 2 Мар 2015 в 03:50

Допустим, у вас есть такой метод на стороне сервера:

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

5
unclelim12 12 Окт 2015 в 04:05