我试图在Jasmine中测试一个相当简单的JavaScript函数,但是第一个语句是因未定义而抛出错误。
myClass.prototype.functiontoBeTested = function() {
var x = this.method()
...
}
上面在Jasmine中抛出错误,因为method
不是函数且未定义。原型被更改为更早使用此方法,出于好奇,我将此方法分配给规范本身的测试对象:
myObject.method = function(){return mockResults;};
所以我决定将this
记录到控制台,而不是它作为我的对象,我看到Window {top: Window, location: Location, document: document, window: Window, external: Object…}
看起来并不正确。我之前在测试使用this
的Jasmine中的函数时遇到过这个问题,但只是更改了源代码以按名称引用对象,因为函数被分配给闭包内的某个东西。在这种情况下,我无法做到这一点,我很好奇为什么this
指的是意外的事情(至少对我而言)。
编辑:有关测试用例的要求的详细信息:
it("updates the control count", function(){
var mockResults = { ... };
myObject.method = function() {return mockResults;};
expect(myObject.method).not.toThrow();
});
现在我只是试图在测试期间让方法执行完成。要测试的功能会更新某些HTML组件上的文本,我会在我能够实际运行之后验证这些组件。导致错误的方法是函数的第一行,并且只是被调用对象的访问器方法。在实际执行中,var x = this.method()
运行没有问题。在jasmine var x = this.method()
中测试时会因为method()
未定义this
而引发错误。而不是this
引用调用对象,它指的是窗口。这不会发生,但仅限于使用Jasmine进行测试。即使我在上面的测试执行之前强行为测试对象定义它,这个方法也是未定义的。当我决定在源代码中将this
登录到控制台并意识到它并不是指我希望它引用的内容时。
答案 0 :(得分:0)
在JavaScript this
中,方法取决于调用它的上下文。当您拨打电话myObject.method()
时,method
的上下文中已调用myObject
,因此this
为myObject
。
当您将函数传递给Jasmine toThrow
匹配器时,它会在传递时调用它(see source code):
try {
actual();
} catch (e) {
// ....
}
此处,actual()
是您方法的调用。它没有任何特定的上下文,因此默认情况下它将从window
上下文调用。
解决方案是明确bind您method
至myObject
,如下所示:
expect(myObject.method.bind(myObject)).not.toThrow();
对问题的肯定,你可以在那里找到更多细节: