Метеор / Жасмин / Скорость: как проверить серверный метод, требующий входа в систему пользователя?
Используя скорость / жасмин, я немного застрял в том, как я должен протестировать серверный метод, требующий, чтобы в данный момент был вошедший в систему пользователь. Есть ли способ заставить Метеор думать, что пользователь вошел в систему через заглушку / фейк?
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 ответа
Что вы можете сделать, это добавить пользователей только в ваш набор тестов. Вы можете сделать это, заполнив этих пользователей в тестовом сценарии на стороне сервера:
Что-то вроде:
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 есть нужные пользователи с правильными ролями.
Допустим, у вас есть такой метод на стороне сервера:
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
Я думаю что Meteor.server.method_handlers["nameOfMyMethod"]
позволяет вызвать / применить метод Метеор и снабжение this
как первый параметр хотя бы в текущей версии (1.3.3)
this.userId = userId;
Meteor.server.method_handlers["cart/addToCart"].apply(this, arguments);
Что вы тестируете и почему требуется, чтобы пользователь вошел в систему? Большинству методов, которые у меня есть, нужен пользовательский объект, в который я передаю пользовательский объект. Это позволяет мне звонить из теста без фактического входа в систему. Поэтому при фактическом выполнении кода я бы прошел...
var r = myMethod(Meteor.user());
но при запуске из теста я бы назвал как...
it('should be truthy', function () {
var r = myMethod({_id: '1', username: 'testUser', ...});
expect(r).toBeTruthy();
});