茉莉花模拟窗口对象

我如何模拟窗口对象? 我正在做Firefox的扩展,我想用茉莉花的JavaScripttesting。

在我的JavaScript我有

function submit() { ... var url = window.arguments[0]; ... } 

很明显,我必须在茉莉花模拟window.arguments [0],因为如果不从window.openDialog传递任何参数,该对象不存在

这是我试图嘲笑它与“与”

it("should submit to server", function() { var localContext = { "window": { arguments: ["http://localhost"] } } with(localContext);
it("should submit to server", function() { var localContext = { "window": { arguments: ["http://localhost"] } } with(localContext); 

但是我仍然得到这个错误TypeError:不能读取未定义的属性'0',就像当testing运行时window.arguments [0]被真正的窗口消灭,因为如果我

window.arguments[0]

在testing中,它正确地打印出“http:// localhost”。 但是当涉及到submit()方法时,它显示了window.argument未定义的错误。

问题是你只是覆盖窗口对象的属性。 如果你能做到这一点,浏览器也可以做到这一点。 因此,嘲笑每个人都可以访问的全局对象的函数或属性通常不是一个好主意,因为当您尝试访问它们时,您无法确定所做的更改会在那里。

这使我dependency injection 。 它是一个常见的模式,使您的代码单元可testing,重点单位 。 这是什么意思。 当你创build一个新的对象或访问一个全局对象时,你不仅要testing你的单元function,还要testing新创build的或全局对象的function。 为了做到这一点,你不要在你的单元中创build新的对象,而是把它们传入。 通常情况下,你会在构造函数中这样做,但是在JavaScript函数中,函数体是构造函数的对象,你也可以简单地将依赖关系传递给你的函数。

所以在你的情况下,函数依赖于全局窗口对象。 所以不是试图访问全局窗口对象,而是将它作为parameter passing给你的函数。 这样做可以将生产代码中的窗口对象和具有参数属性的简单JavaScript对象传递到您的testing中:

 function youWannaTest(w){ console.log(w.arguments[0]); } 

在你的扩展调用这样的function:

 youWannaTest(window); 

在你的testing中调用这样的function:

 youWannaTest({arguments: ['someValue']}); 

我也认为dependency injection是最干净的解决scheme。

你的JS:

 function submit(_window) { _window = _window || window ... var url = _window.arguments[0]; ... } 

你的unit testing:

 it('works like a dream', function () { var _window = { arguments: ['url'] } expect(submit(_window)).toBeTotallyAwesome() }) 

是的,你可以模拟窗口对象。

你将不得不做的第一件事是在你的JS代码中进行一个更改:用$ windowreplace窗口

然后,你可以使用下面的代码模拟窗口:

 var window = { arguments : ['url'] }; 

现在在你的spec文件中:在每个块之前

 $controller('controllerName', {$window : window});