该注册上准备处理程序应注册另一个函数,而不是一个匿名代码块的功能。然后,您可以测试调用$ .ready()的代码与运行就绪的代码分开。所以,你必须:
- 一个测试,以验证正确的功能被设置为准备处理
- 另一项测试,以验证准备处理程序做正确的东西
为了测试场景1,你需要为jQuery注入一个测试双精度。这很难,就像你重新定义$或jQuery一样,你会把其他代码依赖于其他处理(如测试运行器)。同时你的代码可能仍然希望在使用像数组串联这样的实用方法时直接调用jQuery。任何反转控制模式都应该解决这个问题(http://martinfowler.com/articles/injection.html)。
总之,这是一个使用构造器注入(使用JSMock的嘲讽库和QUnit(的jQuery)用于测试运行)一些代码:
// the code
var createComponent = function(_$) {
var that = {};
that.OnStart = function() {
_$.ready(this.OnReady);
};
that.OnReady = function() {
};
return that;
};
// the test
test("OnStart associates the ready handler", function() {
var sut;
var mock$ = mc.createMock($);
mock$.expects().ready(isA.TypeOf(Function)).andStub(function(callback) {
equals(callback, sut.OnReady);
});
sut = createComponent(mock$);
sut.OnStart();
mc.verify();
});
test("OnReady does the right stuff", function() {
//etc
});
我用这个一般模式为JS所有事件处理程序...您可能更喜欢使用原型类型类。当您将函数作为参数传递给jQuery时,您需要知道在调用这些回调函数时,“this”值不会由jQuery设置。在测试中,这会因为equals(callback,sut.OnReady)不再通过而中断。为了解决这个问题,你需要让事件处理程序直接指定每个实例的成员。你可以想象一下,当有一些好的应用程序需要一个列表的时候,但是这表明使'OnReady'成为一个不依赖于'this'的成员。
var Component = function(_$) {
this._$ = _$;
// repeat for each event handler thats tested
this.OnReady = function() {
Component.prototype.OnReady.apply(this);
}
}
Component.prototype.Start = function() {
this._$.ready(this.OnReady);
}
Component.prototype.OnReady = function() {
}
你想要测试什么?只需测试代码,为什么你不应该测试你的代码在做什么? – powtac 2009-11-26 00:37:17
我试图测试$(document).ready(function(){//测试这些代码});内部的逻辑。我正在使用JsTestDriver来测试我的JavaScript。目前,我无法访问document.ready块。 – BeraCim 2009-11-30 05:59:25