Javascript 用 Sinon 存根 window.location.href
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/36678302/
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
Stubbing window.location.href with Sinon
提问by Francesco Pezzella
I am trying to test some client-side code and for that I need to stub the value of window.location.href
property using Mocha/Sinon.
我正在尝试测试一些客户端代码,为此我需要window.location.href
使用 Mocha/Sinon存根属性的值。
What I have tried so far (using this example):
到目前为止我尝试过的(使用这个例子):
describe('Logger', () => {
it('should compose a Log', () => {
var stub = sinon.stub(window.location, 'href', 'http://www.foo.com');
});
});
The runner displays the following error:
运行程序显示以下错误:
TypeError: Custom stub should be a function or a property descriptor
类型错误:自定义存根应该是函数或属性描述符
Changing the test code to:
将测试代码更改为:
describe('Logger', () => {
it('should compose a Log', () => {
var stub = sinon.stub(window.location, 'href', {
value: 'foo'
});
});
});
Which yields this error:
这产生了这个错误:
TypeError: Attempted to wrap string property href as function
类型错误:试图将字符串属性 href 包装为函数
Passing a function as third argument to sinon.stub
doesn't work either.
将函数作为第三个参数传递给sinon.stub
也不起作用。
Is there a way to provide a fake window.location.href
string, also avoiding redirection (since I'm testing in the browser)?
有没有办法提供假window.location.href
字符串,同时避免重定向(因为我在浏览器中测试)?
采纳答案by try-catch-finally
Stubs cannot replace attributes, only functions.
存根不能替换属性,只能替换函数。
The error thrown reinforces this:
抛出的错误强化了这一点:
TypeError: Custom stub should be a function or a property descriptor
类型错误:自定义存根应该是函数或属性描述符
From the documentation:
从文档:
When to use stubs?
Use a stub when you want to:
Control a method's behavior from a test to force the code down a specific path. Examples include forcing a method to throw an error in order to test error handling.
When you want to prevent a specific method from being called directly (possibly because it triggers undesired behavior, such as a XMLHttpRequest or similar).
什么时候使用存根?
需要时使用存根:
从测试中控制方法的行为以强制代码沿特定路径运行。示例包括强制方法抛出错误以测试错误处理。
当您想阻止直接调用特定方法时(可能是因为它触发了不希望的行为,例如 XMLHttpRequest 或类似行为)。
http://sinonjs.org/releases/v2.0.0/stubs/
http://sinonjs.org/releases/v2.0.0/stubs/
Possible solution
可能的解决方案
While many builtin objects can be replaced (for testing) some can't. For those attributes you could create facade objects which you then have to use in your code and being able to replace them in tests.
虽然许多内置对象可以被替换(用于测试),但有些不能。对于这些属性,您可以创建外观对象,然后您必须在代码中使用这些对象,并能够在测试中替换它们。
For example:
例如:
var loc = {
setLocationHref: function(newHref) {
window.location.href = newHref;
},
getLocationHref: function() {
return window.location.href;
}
};
Usage:
用法:
loc.setLocationHref('http://acme.com');
You can then in your test write
然后你可以在你的测试中写
var stub = sinon.stub(loc, 'setLocationHref').returns('http://www.foo.com');
Note the chained returns()
call. There was another error in your code: the third argument has to be a function, not value on another type. It's a callback, not what the attribute should return.
注意链式returns()
调用。您的代码中存在另一个错误:第三个参数必须是函数,而不是其他类型的值。这是一个回调,而不是属性应该返回的内容。
回答by KhaledMohamedP
You need to use global
to mock the window
object for your test in beforeEach
or it
您需要使用global
嘲笑的window
对象为您的测试中beforeEach
或it
e.g.
例如
it('should compose a Log', () => {
global.window = {
location: {
href: {
value: 'foo'
}
}
}
//.... call the funciton
});
回答by Danny Andrews
Use window.location.assign(url)
instead of overwriting the value of window.location
. Then you can just stub the assign
method on the window.location
object.
使用window.location.assign(url)
而不是覆盖 的值window.location
。然后你可以assign
在window.location
对象上存根方法。
http://www.w3schools.com/jsref/met_loc_assign.asp
http://www.w3schools.com/jsref/met_loc_assign.asp
UPDATE: I tested this in a headless browser, but it may not work if you run your tests in Chrome. See @try-catch-finally's response.
更新:我在无头浏览器中对此进行了测试,但如果您在 Chrome 中运行测试,它可能无法正常工作。请参阅@try-catch-finally 的回复。