我按照基本" Todo教程"学习Meteor。来自官方网站。我对"测试"有问题。步。 我有一个方法的基本测试,它看起来像这样:
if (Meteor.isServer) {
describe('Tasks', () => {
describe('methods', () => {
const userId = Random.id();
let taskId;
beforeEach(() => {
Tasks.remove({});
taskId = Tasks.insert({
text: 'test task',
createdAt: new Date(),
owner: userId,
username: 'tmeasday',
});
});
it('can delete owned task', () => {
const deleteTask = Meteor.server.method_handlers['tasks.remove'];
const invocation = { userId };
deleteTask.apply(invocation, [taskId]);
assert.equal(Tasks.find().count(), 0);
});
});
});
}
此测试失败,错误:
Error: Meteor.userId can only be invoked in method calls. Use this.userId in publish functions.
at AccountsServer.userId (packages/accounts-base/accounts_server.js:82:13)
at Object.Meteor.userId (packages/accounts-base/accounts_common.js:257:19)
at Object.Meteor.methods.tasks.remove (imports/api/tasks.js:37:35)
at Test.<anonymous> (imports/api/tasks.tests.js:27:28)
at run (packages/practicalmeteor:mocha-core/server.js:34:29)
at Context.wrappedFunction (packages/practicalmeteor:mocha-core/server.js:63:33)
IMO,这个错误信息是有争议的,因为它说的是我没有做出的错误,因为正如我从错误消息第4行看到的那样,stacktrace指向Method声明体,这个:
'tasks.remove' (taskId) {
check(taskId, String);
const task = Tasks.findOne(taskId);
if (task.owner !== Meteor.userId()) { // <- ERROR MESSAGE POINTS TO THIS LINE
// If the task is private, make sure only the owner can delete it
throw new Meteor.Error('not-authorized');
}
Tasks.remove(taskId);
},
教程代码与我的代码有一点不同:我从!todo.private
语句中删除了条件if
,所以在原始教程中它们看起来像这样:
if (!task.private && task.owner !== Meteor.userId()) {...
IMO,这一变化使得测试达到失败的表达,因为测试通过了原始代码。
我还提到将Meteor.userId()
更改为this.userId
会使测试通过,应用程序也会像以前一样工作。
所以,我的问题基本上是:为什么错误消息显示我有争议的(IMO)信息以及在方法中使用this.userId
和Meteor.userId()
之间有什么区别?
我的完整&#34; Todo教程&#34;项目代码可在以下位置找到:https://github.com/kemsbe/simple-todo
答案 0 :(得分:2)
基本上this.userId使用函数的this
上下文,Meteor.userId()使用当前光纤获取userId。
如果您希望代码与Meteor.userId()一起使用,则需要在光纤中运行您的功能。你可以做的另一件事是发送meteor.userId,就像How to unit test a meteor method with practicalmeteor:mocha
中所解释的那样