测试流星 - 使用单元测试而不是集成测试来测试允许/拒绝
Testing meteor - testing allow / deny with a unit test instead of integration test
我有一个应用程序代码以下列方式限制文档
Docs.allow({
insert: function(userId, doc){
return !!userId
},
update: function(userId, doc){
return userId && doc.owner == userId;
}
})
目前,我只能运行 进行实际 http 调用的集成测试。我无法在被测系统外部存根组件(Meteor 当前用户)(允许/拒绝规则)。
it("should succeed if user is authenticated", function(done) {
Meteor.loginWithPassword(’shawn@abc.com', ‘hahaha', function(err){
expect(err).toBe(undefined);
Doc = Docs.insert({title: 'abc',
category: 'Finance'},
function(err, id){
expect(err).toBeUndefined();
expect(id).not.toBeUndefined();
done();
});
});
});
it("should fail if user is not authenticated", function(done) {
Meteor.logout(function(){
doc = Docs.insert({title: 'abc',
category: 'Finance',
owner: '1232131'},
function(err, id){
expect(err).not.toBeUndefined();
done();
});
});
});
这使我的测试非常慢,尤其是当我要测试很多路径时。有没有办法让我将此测试移至较低级别的单元测试?
此测试在服务器代码上练习执行路径,这是 allow/deny 规则所在的位置。
这里的测试没有做client-server的集成,你的client集成测试做的很好
您可以使用单元测试覆盖代码中的所有执行路径,然后减少集成测试,从而获得您想要的速度。
你应该尽可能多的进入下层,但不要面面俱到。您仍然想确保集成也有效。
describe('Doc security rules', function () {
var _oldAllowRules;
beforeAll(function () {
var _allowRules = null;
// keep hold of the old Docs.allow method so we can restore in the after step
_oldAllowRules = Docs.allow;
// override the Docs.allow method so we can isolate the allow rules code
Docs.allow = function (allowRules) {
_allowRules = allowRules;
};
});
afterAll(function () {
// restore the Docs.allow method
Docs.allow = _oldAllowRules;
});
it('insert deny access to non-logged in users', function () {
// Execute
// you can now exercise the allowRules directly
var response = _allowRules.insert(null, {});
// Verify
expect(response).toBe(false);
});
it('update allows for doc owner', function () {
// you can do it all with one step
expect(_allowRules.update(1234, {owner: 1234})).toBe(true);
});
it('update denies for logged out user', function () {
expect(_allowRules.update(null, {})).toBe(false);
});
it('update denies for non document owner', function () {
expect(_allowRules.update(1234, {owner: 5678})).toBe(false);
});
});
基于 Meteor 测试手册的答案...Stories.allow
模拟是在应用程序代码加载后定义的。因此,它没有效果。
如 https://github.com/Sanjo/meteor-jasmine#stubs、
中所述
Files in tests/jasmine folder (or a subfolder of it) that end with -stubs.js or -stub.js are treated as stubs and are loaded before the app code.
所以为了使流星测试手册的答案有效,我们必须在 -stubs.js 文件中定义存根/模拟。这就是我在 z-security-stubs.js
.
上所做的
注意我在文件名前加了'z'前缀,因为meteor加载的文件在同级子目录中是按字母顺序排列的。我们必须确保我们自定义的存根在 Velocity 自动生成的 package-stubs.js
和 packageMocksSpec.js
之后加载。
考虑到这一点,z-security-stubs.js
可以包含如下内容:
Mongo.Collection.prototype.allow = function(rules){
this._velocityAllow = rules;
}
Mongo.Collection.prototype.deny = function(rules){
this._velocityDeny = rules;
}
这在集合实例的 属性 中保留了对我们的允许/拒绝安全规则的引用(例如,文档、文件或您的集合的任何名称);
之后我们可以参考这个属性中的安全函数,进行断言:
describe("Docs security rules", function() {
var allow;
beforeEach(function(){
allow = Docs._velocityAllow;
});
it("insert deny access to non-logged in users", function() {
var response = allow.insert(null, {});
expect(response).toBe(false);
});
it("insert allow access to logged in users", function() {
var response = allow.insert(true, {});
expect(response).toBe(true);
});
it("update allow access to logged in users who are owners", function() {
var response = allow.insert(2, {owner: 2});
expect(response).toBe(true);
});
it("update deny access to non-logged in users", function() {
var response = allow.update(null, {owner: 2});
expect(response).toBe(false);
});
it("update deny access to logged in users who are not owners", function() {
var response = allow.update(1, {owner: 2});
expect(response).toBe(false);
});
});
我有一个应用程序代码以下列方式限制文档
Docs.allow({
insert: function(userId, doc){
return !!userId
},
update: function(userId, doc){
return userId && doc.owner == userId;
}
})
目前,我只能运行 进行实际 http 调用的集成测试。我无法在被测系统外部存根组件(Meteor 当前用户)(允许/拒绝规则)。
it("should succeed if user is authenticated", function(done) {
Meteor.loginWithPassword(’shawn@abc.com', ‘hahaha', function(err){
expect(err).toBe(undefined);
Doc = Docs.insert({title: 'abc',
category: 'Finance'},
function(err, id){
expect(err).toBeUndefined();
expect(id).not.toBeUndefined();
done();
});
});
});
it("should fail if user is not authenticated", function(done) {
Meteor.logout(function(){
doc = Docs.insert({title: 'abc',
category: 'Finance',
owner: '1232131'},
function(err, id){
expect(err).not.toBeUndefined();
done();
});
});
});
这使我的测试非常慢,尤其是当我要测试很多路径时。有没有办法让我将此测试移至较低级别的单元测试?
此测试在服务器代码上练习执行路径,这是 allow/deny 规则所在的位置。
这里的测试没有做client-server的集成,你的client集成测试做的很好
您可以使用单元测试覆盖代码中的所有执行路径,然后减少集成测试,从而获得您想要的速度。
你应该尽可能多的进入下层,但不要面面俱到。您仍然想确保集成也有效。
describe('Doc security rules', function () {
var _oldAllowRules;
beforeAll(function () {
var _allowRules = null;
// keep hold of the old Docs.allow method so we can restore in the after step
_oldAllowRules = Docs.allow;
// override the Docs.allow method so we can isolate the allow rules code
Docs.allow = function (allowRules) {
_allowRules = allowRules;
};
});
afterAll(function () {
// restore the Docs.allow method
Docs.allow = _oldAllowRules;
});
it('insert deny access to non-logged in users', function () {
// Execute
// you can now exercise the allowRules directly
var response = _allowRules.insert(null, {});
// Verify
expect(response).toBe(false);
});
it('update allows for doc owner', function () {
// you can do it all with one step
expect(_allowRules.update(1234, {owner: 1234})).toBe(true);
});
it('update denies for logged out user', function () {
expect(_allowRules.update(null, {})).toBe(false);
});
it('update denies for non document owner', function () {
expect(_allowRules.update(1234, {owner: 5678})).toBe(false);
});
});
基于 Meteor 测试手册的答案...Stories.allow
模拟是在应用程序代码加载后定义的。因此,它没有效果。
如 https://github.com/Sanjo/meteor-jasmine#stubs、
中所述Files in tests/jasmine folder (or a subfolder of it) that end with -stubs.js or -stub.js are treated as stubs and are loaded before the app code.
所以为了使流星测试手册的答案有效,我们必须在 -stubs.js 文件中定义存根/模拟。这就是我在 z-security-stubs.js
.
注意我在文件名前加了'z'前缀,因为meteor加载的文件在同级子目录中是按字母顺序排列的。我们必须确保我们自定义的存根在 Velocity 自动生成的 package-stubs.js
和 packageMocksSpec.js
之后加载。
考虑到这一点,z-security-stubs.js
可以包含如下内容:
Mongo.Collection.prototype.allow = function(rules){
this._velocityAllow = rules;
}
Mongo.Collection.prototype.deny = function(rules){
this._velocityDeny = rules;
}
这在集合实例的 属性 中保留了对我们的允许/拒绝安全规则的引用(例如,文档、文件或您的集合的任何名称);
之后我们可以参考这个属性中的安全函数,进行断言:
describe("Docs security rules", function() {
var allow;
beforeEach(function(){
allow = Docs._velocityAllow;
});
it("insert deny access to non-logged in users", function() {
var response = allow.insert(null, {});
expect(response).toBe(false);
});
it("insert allow access to logged in users", function() {
var response = allow.insert(true, {});
expect(response).toBe(true);
});
it("update allow access to logged in users who are owners", function() {
var response = allow.insert(2, {owner: 2});
expect(response).toBe(true);
});
it("update deny access to non-logged in users", function() {
var response = allow.update(null, {owner: 2});
expect(response).toBe(false);
});
it("update deny access to logged in users who are not owners", function() {
var response = allow.update(1, {owner: 2});
expect(response).toBe(false);
});
});