在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) { ... }
但它只在直接调用方法时才有效。
我不确定如何使用正确的安全验证来测试我的客户端代码。如何使用经过身份验证的用户测试我的客户端代码?
答案 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()
这基本上在以下资源中描述/讨论:
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;
});
注意:我经常听说这是不好的测试,我不同意。特别是集成测试应该尽可能好地模拟真实行为,并且应该使用较少的模拟/间谍作为单元测试。