1
這是foo.js
:如何確保測試對象屬性的更改不會傳播到其他測試用例?
var Foo;
Foo = function() {
var foo = {};
foo.get = function (url) {
// [..]
return Foo.get(url);
};
return foo;
};
Foo.get = function (url) {};
module.exports = Foo;
這是一個測試案例foo.js
:
var expect = require('chai').expect,
sinon = require('sinon');
describe('foo', function() {
var Foo,
foo;
beforeEach(function() {
Foo = require('foo.js');
foo = Foo();
});
describe('.get(url)', function() {
it('passes the call to Foo.get(url)', function() {
var spy = sinon.spy();
// We are going to spy on Foo.get:
Foo.get = spy;
foo.get('http://');
// [..]
});
it('does something else', function() {
foo.get('http://');
// Here Foo.get persists to refer to an instance of sinon.spy.
// How to make sure that the tests are indepeondent?
});
});
});
我已覆蓋Foo.get
屬性來窺探它。
我希望用beforeEach
到require('foo.js')
將覆蓋Foo
對象,並下試不知道以前的更改對象。
顯而易見的解決方案是存儲對前一個屬性狀態的引用並在測試後恢復它,例如,
it('passes the call to Foo.get(url)', function() {
var spy = sinon.spy(),
Fooget = Foo.get;
// We are going to spy on Foo.get:
Foo.get = spy;
foo.get('http://');
// [..]
Foo.get = Fooget;
});
但是,這種方法很容易出錯。
這樣做是重寫模塊&把它變成一個構造的一種方法:
module.exports = function() {
var Foo;
Foo = function() {
var foo = {};
foo.get = function (url) {
// [..]
return Foo.get(url);
};
return foo;
};
Foo.get = function (url) {};
};
然後在每次測試之前建立一個新的實例:
describe('foo', function() {
var Foo,
foo;
beforeEach(function() {
Foo = require('foo.js')();
foo = Foo();
});
describe('.get(url)', function() {
// [..]
});
});
不理想,但因爲這會影響庫的API。
sinon如何恢復'Foo.get'的屬性值? – Gajus 2014-10-31 10:49:10
使用此語法:'this.sinon.spy(Foo,「get」)'。這樣,因爲它知道字符串屬性名稱,它可以將它恢復到未加密版本。 – 2014-10-31 10:50:35
這很有道理。 – Gajus 2014-10-31 10:51:08