问题描述
如何模拟窗口对象?我正在进行firefox扩展,我想使用jasmine进行javascript测试。
How do I mock window object? I'm doing firefox extension and I want to use jasmine for javascript testing.
在我的javascript中我有
In my javascript I have
function submit() {
...
var url = window.arguments[0];
...
}
显然,我必须jasmine中的mock window.arguments [0]因为如果没有从window.openDialog传递任何参数该对象不存在
Obviously, I have to mock window.arguments[0] in jasmine because that object doesn't exists if not passing any parameter from window.openDialog
这是我尝试用with
This is my attempt to mock it with "with"
it("should submit to server", function() {
var localContext = {
"window": {
arguments: ["http://localhost"]
}
}
with(localContext);
但我仍然收到此错误TypeError:无法读取未定义的属性'0',就像测试运行时一样window.arguments [0]被真实窗口消灭了,因为如果我这样做了
But I still get this error TypeError: Cannot read property '0' of undefined, it's like when the test is run window.arguments[0] gets wiped out with the real window, because if I do
window.arguments [0]
在测试中,打印出http :// localhost正确。但是当涉及到submit()方法时,它会显示window.argument为undef的错误ined。
inside the test, it prints out "http://localhost" correctly. but when it comes to submit() method it shows the error that window.argument is undefined.
推荐答案
问题是你只是覆盖了窗口对象的属性。如果你能做到这一点,浏览器也可以做到这一点。因此,模拟每个人都可以访问的全局对象的函数或属性通常不是一个好主意,因为当您尝试访问它们时,您永远无法确定您的更改是否存在。
The problem is that you just overwrite a property of the window object. And if you can do that, the browser can do that as well. So mocking a function or property of a global object that everyone can access isn't a good idea in general, because you can never be sure that your changes will be there when you try to access them.
这让我想到。它是一种使代码单元可测试的常见模式,重点是单元。这是什么意思。无论何时创建新对象或访问全局对象,您不仅要测试单元功能,还要测试新创建的或全局对象的功能。要预先添加,请不要在单元中创建新对象,而是将其传递给。通常你会在构造函数中使用它,但是在JavaScript函数中是具有函数体作为构造函数的对象,你也可以将依赖项简单地传递给你的函数。
Which brings me to dependency injection. Its a common pattern to make your code unit testable, with a focus on unit. Whats does it mean. When ever you create a new object or access a global object, you're not only testing your unit functionality, but also the functionality of your newly created or global object. To prepend that, you not create the new objects in your unit, but pass them into. Normally you would to this in the constructor, but as in JavaScript function are objects with the function body as constructor, you can also pass the dependencies simply into your function.
所以在您的情况下,该函数取决于全局窗口对象。因此,不要尝试访问全局窗口对象,而是将其作为参数传递给函数。这样做可以传入生产代码中的window对象和一个带有参数属性的简单JavaScript对象:
So in your case, the function depends on the global window object. So instead of trying to access the global window object, pass it as a parameter into your function. Doing it this way you can pass in the window object in your production code and a simple JavaScript object with an arguments atribute into your test:
function youWannaTest(w){
console.log(w.arguments[0]);
}
在你的分机中调用这样的函数:
In your extension call the function like this:
youWannaTest(window);
在您的测试中,函数如下:
In your test call the function like this:
youWannaTest({arguments: ['someValue']});
这篇关于茉莉花模拟窗口对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!