Javascript 茉莉花模拟窗口对象
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8919370/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
jasmine mock window object
提问by toy
How do I mock window object? I'm doing firefox extension and I want to use jasmine for javascript testing.
我如何模拟窗口对象?我正在做 Firefox 扩展,我想使用 jasmine 进行 javascript 测试。
In my javascript I have
在我的 javascript 中,我有
function submit() {
...
var url = window.arguments[0];
...
}
Obviously, I have to mock window.arguments[0] in jasmine because that object doesn't exists if not passing any parameter from window.openDialog
显然,我必须在 jasmine 中模拟 window.arguments[0] 因为如果不从 window.openDialog 传递任何参数,则该对象不存在
This is my attempt to mock it with "with"
这是我试图用“with”来嘲笑它
it("should submit to server", function() {
var localContext = {
"window": {
arguments: ["http://localhost"]
}
}
with(localContext);
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
但我仍然收到此错误 TypeError: Cannot read property '0' of undefined, 这就像测试运行时 window.arguments[0] 被真实窗口消灭一样,因为如果我这样做
window.arguments[0]
window.arguments[0]
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.
在测试中,它正确打印出“http://localhost”。但是当涉及到 submit() 方法时,它显示了 window.argument 未定义的错误。
回答by Andreas K?berle
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.
问题是你只是覆盖了 window 对象的一个属性。如果你能做到,浏览器也能做到。因此,模拟每个人都可以访问的全局对象的函数或属性通常不是一个好主意,因为当您尝试访问它们时,您永远无法确定您的更改会在那里。
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 unitfunctionality, 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.
这让我想到了依赖注入。它是使您的代码单元可测试的常见模式,重点是unit。这是什么意思。当您创建新对象或访问全局对象时,您不仅要测试单元功能,还要测试新创建或全局对象的功能。在此之前,您不是在您的unit 中创建新对象,而是将它们传递给。通常,您会在构造函数中使用 this,但在 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:
因此,在您的情况下,该函数取决于全局窗口对象。因此,与其尝试访问全局 window 对象,不如将其作为参数传递给您的函数。通过这种方式,您可以将生产代码中的 window 对象和一个带有参数属性的简单 JavaScript 对象传递到您的测试中:
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']});
回答by A.Williams
I also think dependency injection is the cleanest solution.
我也认为依赖注入是最干净的解决方案。
Your JS:
你的JS:
function submit(_window) {
_window = _window || window
...
var url = _window.arguments[0];
...
}
Your unit tests:
您的单元测试:
it('works like a dream', function () {
var _window = { arguments: ['url'] }
expect(submit(_window)).toBeTotallyAwesome()
})
回答by Ankit Shah
Yes, You can mock window object.
是的,您可以模拟窗口对象。
The first thing you will have to do is make one change in your JS code : Replace windowwith $window.
你必须做的第一件事是做一个改变你的JS代码:替换窗口以$窗口。
Then, You can mock window using below code:
然后,您可以使用以下代码模拟窗口:
var window = {
arguments : ['url']
};
now in your spec file : in beforeEach block
现在在您的规范文件中:在 beforeEach 块中
$controller('controllerName', {$window : window});