How to test a meteor method that relies on Meteor.user()

ぃ、小莉子 提交于 2019-12-13 05:03:00

问题


I am trying to determine the best way to test my code and am running into complications from every direction I've tried.

The basic code is this (though far more complex due to several layers of "triggers" that actually implement this):

  1. Client populates an object
  2. Client calls a meteor method and passes the object
  3. Meteor method uses Meteor.user() to get the current user, adds a "createdby" attribute to the object, inserts the object and then creates another object (of a different type) with various attributes that depend on the first object, as well as a bunch of other things already in the database

I'm trying to use Velocity and Jasmine. I'd prefer to integration test these steps to create the first object and then test that the second object is properly created.

My problem is that if I do it on the server, the Meteor.user() call doesn't work. If I do it on the client, I need to subscribe to a large number of collections in order for the logic to work, which seems kludgy.

Is there a better approach? Is there a way to simulate or mock a user login in a server integration test?


回答1:


In your jasmine test you can mock a call to Meteor.user() like so:

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



回答2:


You may want to specify a userId or change logged state depending on executed test. I then recommend to create meteor methods in your test project:

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



回答3:


If you don't want to rely on a complete lib just for this single usecase, you can easily mock your Meteor.urser() with beforeEach and afterEach:

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

});

It makes sure, that Meteor.user() only returns the user you created in beforeEach. This it at least a fine thing, when you want to test everything else and assume, that the user creation and Meteor.user() is working as expected (which is the essence of mocking, as I can see so far).



来源:https://stackoverflow.com/questions/30940204/how-to-test-a-meteor-method-that-relies-on-meteor-user

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!