如何测试依赖Meteor.user()的流星方法

时间:2015-06-19 14:06:14

标签: testing meteor jasmine

我正在尝试确定测试代码的最佳方法,并且遇到了我尝试的每个方向的复杂问题。

基本代码是这样的(虽然由于几层"触发器和#34实际上实现了这一点而变得更加复杂):

  1. 客户端填充对象
  2. 客户端调用meteor方法并传递对象
  3. Meteor方法使用Meteor.user()获取当前用户,添加"创建"属性到对象,插入对象,然后创建另一个对象(具有不同类型),具有依赖于第一个对象的各种属性,以及数据库中已有的一堆其他东西
  4. 我试图使用Velocity和Jasmine。我更喜欢集成测试这些步骤来创建第一个对象,然后测试第二个对象是否正确创建。

    我的问题是,如果我在服务器上执行此操作,则Meteor.user()调用不起作用。如果我在客户端上执行此操作,我需要订阅大量的集合才能使逻辑工作,这看起来很糟糕。

    有更好的方法吗?有没有办法在服务器集成测试中模拟或模拟用户登录?

3 个答案:

答案 0 :(得分:2)

在茉莉花测试中,您可以像这样模拟对Meteor.user()的调用:

spyOn(Meteor, "user").and.callFake(function() {
    return 1234; // User id
});

答案 1 :(得分:0)

您可能希望根据执行的测试指定userId或更改记录状态。然后我建议在测试项目中创建流星方法:

logIn = function(userId) {
    Meteor.call('logIn', userId);
};

logOut = function() {
    Meteor.call('logOut');
}


Meteor.userId = function() {
    return userId;
};

Meteor.user = function() {
    return userId ? {
        _id: userId,
        username: 'testme',
        emails: [{
            address: 'test@domain.com'
        }],
        profile: {
            name: 'Test'
        }
    } : null;
};

Meteor.methods({
    logIn: function(uid) {
        userId = uid || defaultUserId;
    },
    logOut: function() {
        userId = null;
    }
});

答案 2 :(得分:0)

如果你不想仅仅为这个单一用例依赖一个完整的lib,你可以使用beforeEach和afterEach轻松模拟你的Meteor.urser():

import {chai, assert} from 'meteor/practicalmeteor:chai';
import {Meteor} from 'meteor/meteor';
import {Random} from 'meteor/random';

describe('user mocking', () => {

    let userId = null;
    let userFct = null;

    const isDefined = function (target) {
        assert.isNotNull(target, "unexpected null value");
        assert.isDefined(target, "unexpected undefined value");

        if (typeof target === 'string')
            assert.notEqual(target.trim(), "");
    };

    //------------------------------------------//

    beforeEach(() => {

        // save the original user fct
        userFct = Meteor.user;

        // Generate a real user, otherwise it is hard to test roles
        userId = Accounts.createUser({username: Random.id(5)});
        isDefined(userId);

        // mock the Meteor.user() function, so that it
        // always returns our new created user
        Meteor.user = function () {
            const users = Meteor.users.find({_id: userId}).fetch();
            if (!users || users.length > 1)
                throw new Error("Meteor.user() mock cannot find user by userId.");
            return users[0];
        };
    });

    //------------------------------------------//

    afterEach(() => {
        //remove the user in the db
        Meteor.users.remove(userId);
        // restore user Meteor.user() function
        Meteor.user = userFct;
        // reset userId
        userId = null;
    });

    it("works...", () => {
        // try your methods which make use of 
        // Meteor.user() here
    });

});

确保Meteor.user()仅返回您在beforeEach中创建的用户。这至少是一件好事,当你想测试其他一切并假设用户创建和Meteor.user()按预期工作时(这是模拟的本质,正如我目前所见)。