测试Meteor服务器方法使用经过身份验证的用户调用客户端代码

时间:2017-07-12 20:29:30

标签: javascript meteor

在Meteor应用程序中,我需要测试一些具有语句的客户端代码,例如

Meteor.call('foo', param1, param2, (error, result) => { .... });

并且,在这些方法中,我进行了安全检查,以确保该方法只能由经过身份验证的用户调用。但是,所有这些测试都在测试期间失败,因为没有用户通过身份验证。

在每个服务器方法中,我都会检查这样的用户

if (!Roles.userIsInRole(this.userId, [ ...roles ], group)) {
  throw new Meteor.Error('restricted', 'Access denied');
}

我已经读过我们应该直接导出服务器方法并直接测试它们,我实际上是为服务器方法测试做的,但是这里不可能,因为我需要测试依赖于{{1的客户端代码}}

我当然也不希望Meteor.call到处都是......

我想也许包装我这样导出的方法:

if (Meteor.isTest || Meteor.isAppTest) { ... }

但它只在直接调用方法时才有效。

我不确定如何使用正确的安全验证来测试我的客户端代码。如何使用经过身份验证的用户测试我的客户端代码?

1 个答案:

答案 0 :(得分:1)

第一部分:将函数设为导出函数

您只需将导出的方法也添加到流星方法中。

<强>进口/ API / foo.js

export const foo = function(param1, param2){
    if (!Roles.userIsInRole(this.userId, [ ...roles ], group)) {
        throw new Meteor.Error('restricted', 'Access denied');
    }
    //....and other code
};

然后可以在服务器脚本中导入此方法:

<强>进口/启动/ methods.js

import {foo} from '../api/foo.js'

Meteor.methods({
    'foo' : foo
});

因此可以通过Mateor.call调用(&#39; foo&#39; ...)。请注意,回调不能在foo的函数头中定义,因为它是由meteor自动包装的。

<强>进口/ API / foo.tests.js

import {foo} from './foo.js'
if (Meteor.isServer) {
    // ... your test setup    
    const result = foo(...) // call foo directly in your test.
}

这只在服务器上,现在这是在客户端上进行测试的东西:你不会通过Meteor.call来调用它并测试回调结果。因此,在您的客户端,您仍然会测试:

<强>进口/ API / foo.tests.js

if (Meteor.isClient) {
    // ... your test setup    
    Meteor.call('foo', ..., function(err, res) {
        // assert no err and res...
    });
}

其他信息:

我建议你使用mdg:validated-method,它允许上面相同的功能PLUS为你提供更复杂的方法执行控制,文档模式验证和灵活性。它的记录也足以让您实现上述要求。

请参阅:https://github.com/meteor/validated-method

第二部分:使用用户身份验证运行集成测试

此处有两个选项可用于测试您的用户身份验证。它们既有优点也有缺点,并且争论什么是更好的方法。无论你要测试哪一个,你需要编写一个服务器方法,将现有用户添加到给定的角色集。

方法1 - 模拟Meteoring.user()和Meter.userid()

这基本上在以下资源中描述/讨论:

A complete gist example

An example of using either mdg:validated-method or plain methods

Using sinon spy and below also an answer from myself by mocking it manually but this may not apply for your case because it is client-only.使用sinon需要以下包:https://github.com/practicalmeteor/meteor-sinon

方法2 - 复制&#34;真实&#34;应用程序行为

在这种情况下,你可以完全测试而不会嘲笑任何东西。您也可以创建真实用户并在其他测试中使用他们的数据。

在任何情况下,您都需要一个服务器方法,该方法通过给定的名称和角色创建新用户。请注意,它只应位于名称为.test.js的文件中。否则,它可能被视为安全风险。

<强> /imports/api/accounts/accounts.tests.js

Meteor.methods({
    createtestUser(name,password, roles, group);
    const userId = Accounts.createUser({username:name, password:password});
    Roles.addUserToRoles(userId, roles, group);
    return userId;
});

注意:我经常听说这是不好的测试,我不同意。特别是集成测试应该尽可能好地模拟真实行为,并且应该使用较少的模拟/间谍作为单元测试。