Javascript 如何使用摩卡测试Meteor.user

Javascript 如何使用摩卡测试Meteor.user,javascript,testing,meteor,Javascript,Testing,Meteor,我的职能如下: if(Meteor.isServer) { Meteor.methods({ addUser: function (newUser) { check(newUser, { email: String, password: String }); userId = Accounts.createUser(newUser); return userId; }, getUser: function (userID)

我的职能如下:

if(Meteor.isServer) {
Meteor.methods({
    addUser: function (newUser) {
        check(newUser, { email: String, password: String });
        userId = Accounts.createUser(newUser);
        return userId;
    },
    getUser: function (userID) {
        check(userID, String);
        return Meteor.users.find({_id: userID}).fetch();
    }
});
我正试图用摩卡来测试这个功能:

if (Meteor.isServer) {
let testUser;
describe('Users', () => {
    it("Add User", (done) => {

        testUser = {email: 'test@test.test', password: 'test'};

        try {
            testUser._id = Meteor.call('addUser', testUser);
            console.log(Accounts.users.find({_id: testUser._id}).fetch());
            done();
        } catch (err) {
            assert.fail();
        }
    });

    it("Get user", (done) => {
        try {
            Meteor.call('getUser', testUser._id);
            done();
        } catch (err) {
            assert.fail();
        }
    });
});
我知道使用'addUser'的meteor调用是有效的,因为之后的console.log返回我刚创建的用户,当我使用“meteor测试——驱动程序包practicalmeteor:mocha”运行它时,第一个测试通过

但是,接下来我进入了第二个测试部分,在那里我尝试使用meteor调用“getUser”来获取用户,但随后我被卡住了:

'无法调用未定义的'find'方法'


现在我知道区别在于我使用“Meteor.users”而不是“Account.users”来查找用户,但我完全不知道这两者之间有什么区别。我是否应该用Accounts.user方法调用替换所有Meteor.users方法调用?你将如何测试这一点?

我刚刚偶然发现了这篇文章,因为我在几个小时前已经讨论过同样的问题

正如我在代码中看到的,testUser是在第一个单元中定义的(
it(“adduser”…){}
)。我建议您不要在第二个单位中使用第一个单位的值

您可以使用beforeach和afterEach为每个单元创建一个干净的设置,然后在第二个测试单元中创建一个新用户。您还应在每个单元后清理数据库:

describe('Users', () => {

    // use this for each test
    let testUser;


    beforeEach(() => {
        // let's always create a new clean testUser object
        testUser = {email: 'test@test.test', password: 'test'};
    });

    afterEach(() => {
        // Remove the user to keep our db clean
        if (testUser._id)
            Meteor.users.remove(testUser._id);
    });

    it("Add User", (done) => {
        testUser._id = Meteor.call('addUser', testUser);
        const users = Meteor.users.find({_id: testUser._id}).fetch();
        const user = users[0];
        assert.isNotNull(user);
        assert.isDefined(user);
        assert.equal(user._id, testUser._id);
        done();

    });

    it("Get user", (done) => {
        // get a new id from our previously tested
        // (and assume to be working) function
        testUser._id = Meteor.call('addUser', testUser);

        const user = Meteor.call('getUser', testUser._id);
        assert.isNotNull(user);
        assert.isDefined(user);
        assert.equal(user._id, testUser._id);
        done();
    });
});
我还发现,您的“getUser”方法返回一个数组,因此我将其更改为:

getUser: function (userID) {
    check(userID, String);
    const users = Meteor.users.find({_id: userID}).fetch();
    return users[0];
}

所有测试都已测试并正在运行。

实际上,您不需要使用Meteor方法为测试创建用户帐户。拥有专门为测试创建用户帐户的meteor方法是非常肮脏的。您可以使用
dburles:factory
包创建一个测试用户(有或没有角色),然后通过执行以下操作来执行经过验证的方法:
methodName.\u execute(userId,data)
其中userId是一个对象:
{userId:userId}
数据
是该方法的参数。你也可以调用普通的meteor方法来传递一个用户ID作为上下文,但是在这个评论中没有空间去演示你不想测试的行为,我同意。在这个问题中,创建用户帐户的方法是要测试的方法,而不是专门为测试设计的方法。因此,我试图给出一个有用的答案,@justanoob如何以最小的努力解决这个问题。我假设,在其他测试中,暗示用户创建的是一个模拟集合,但我不认为这回答了海报的原始问题。据我所知,这并不能解释“find is undefined”错误,尽管我可能遗漏了一些细节。我遇到了与OP相同的问题,除了Accounts.users.find和Meteor.users.find抛出相同的错误:无法读取未定义的属性“find”。在我的例子中,我不是在一个单元中创建而在另一个单元中签入。我对此感到非常困惑,在任何地方都找不到答案。@Dave在mocha软件包测试中测试用户时,我也遇到过类似的情况。在我的例子中,整个users集合是未定义的,我只是在测试的一开始就创建了它,名为new Mongo.collection,它为我解决了这个问题。也许我会再讨论一遍,然后很快编辑我的答案。