我在尝试测试流星中需要连接用户的方法时遇到了困难。基本上我需要测试应用程序的用户是否可以在其购物车中添加文章。这些方法将测试用户是否已连接,并且为了测试将使用Meteor.userId()。这似乎是单元测试中的问题,因为我得到错误:
“Meteor.userId只能在方法调用或发布中调用。”
到目前为止,我尝试做了这篇文章中提出的建议:How to unit test a meteor method with practicalmeteor:mocha但我不明白解决方案在做什么。
这是我的测试方法:
import { Meteor } from 'meteor/meteor';
import { Random } from 'meteor/random';
import { assert } from 'meteor/practicalmeteor:chai';
import { sinon } from 'meteor/practicalmeteor:sinon';
import { Carts } from '/imports/api/carts/carts.js';
import { Articles } from '/imports/api/articles/articles.js';
import '/imports/api/carts/carts.methods.js';
import { SecurityEnsurer } from '/lib/security/security.js';
function randomInt (low, high) {
return Math.floor(Math.random() * (high - low) + low);
}
if (Meteor.isServer) {
describe('Carts', () => {
describe('methods', () => {
let currentUser;
beforeEach(() => {
Factory.define('user', Meteor.users, {
name: "userTest",
currentUser: {
email: 'user@shop.info',
password: '123456',
}
});
currentUser = Factory.create('user');
sinon.stub(Meteor, 'user');
Meteor.user.returns(currentUser);
Articles.remove({});
articleId = Articles.insert({
name : "azerty",
description : "descTest",
modelNumber : "wxcvbn",
categoryName : "CatTest",
price : 1,
advisedPrice: 2,
supplierDiscount : 0,
brandId : "BrandTest",
isAvailable: true,
restockingTime: 42,
color: "Yellow",
technicals: [
{
name : "GPU",
value : "Intel"
},
],
});
Carts.insert({
owner: currentUser,
entries: [],
});
});
afterEach(() => {
Meteor.user.restore();
Articles.remove({});
Carts.remove({});
});
it('can add article', () => {
let quantity = randomInt(1,50);
const addArticleToCart = Meteor.server.method_handlers['carts.addArticle'];
const invocation = {};
addArticleToCart.apply(invocation, [articleId, quantity]);
assert.equal(Cart.find({owner: currentUser, entries: {$elemMatch: {articleId, quantity}}}).count(), 1);
});
});
});
}
如果有人可以帮我找到如何创建我的测试,这对我很有帮助。
答案 0 :(得分:1)
在调用Meteor方法时伪造用户,我找到的唯一方法是使用mdg:validated-method
包,它提供了一个围绕Meteor方法的框架。这个框架现在似乎是标准(参见Meteor guide),但它需要重新编写你的方法和应用内调用。
在使用此框架描述方法之后,您可以在测试时使用userId参数调用它们,使用这种代码(验证我的方法返回403错误):
assert.throws(function () {
updateData._execute({userId: myExternalUserId}, {
id: dataId,
data: {name: "test"}
});
}, Meteor.Error, /403/);
仅供参考,这是我在进行自动化测试时添加的软件包(使用Meteor 1.6):
meteortesting:mocha
dburles:factory
practicalmeteor:chai
johanbrook:publication-collector
答案 1 :(得分:0)
这是我设置假登录用户以测试发布和方法的方法:
1)创建用户
2)存根,即替换Meteor.user()和Meteor.userId()函数,它们返回方法中当前登录的用户
3)将用户的_id提供给PublicationsCollector,后者会将其发送到您的发布函数中。
这是我的操作方式,希望您可以适应以下情况:
import { Meteor } from 'meteor/meteor';
import { Factory } from 'meteor/dburles:factory';
import { PublicationCollector } from 'meteor/johanbrook:publication-collector';
import { resetDatabase } from 'meteor/xolvio:cleaner';
import faker from 'faker';
import { Random } from 'meteor/random';
import { chai, assert } from 'meteor/practicalmeteor:chai';
import sinon from 'sinon';
// and also import your publish and collection
Factory.define('user', Meteor.users, {
'name': 'Josephine',
});
if (Meteor.isServer) {
describe('Menus', () => {
beforeEach(function () {
resetDatabase();
const currentUser = Factory.create('user');
sinon.stub(Meteor, 'user');
Meteor.user.returns(currentUser); // now Meteor.user() will return the user we just created
sinon.stub(Meteor, 'userId');
Meteor.userId.returns(currentUser._id); // needed in methods
// and create a Menu object in the Menus collection
});
afterEach(() => {
Meteor.user.restore();
resetDatabase();
});
describe('publish', () => {
it('can view menus', (done) => {
const collector = new PublicationCollector({ 'userId': Meteor.user()._id }); // give publish a value for this.userId
collector.collect(
'menus',
(collections) => {
assert.equal(collections.menus.length, 1);
done();
},
);
});
});
});
}
您还可以编写一个测试来调用依赖Meteor.userId()的Meteor方法:
expect(() => { Meteor.call('myMethod'); }).to.not.throw(Meteor.Error);