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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 19:25:56  来源:igfitidea点击:

Stubbing window.location.href with Sinon

javascriptmochasinonstubbing

提问by Francesco Pezzella

I am trying to test some client-side code and for that I need to stub the value of window.location.hrefproperty 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.stubdoesn't work either.

将函数作为第三个参数传递给sinon.stub也不起作用。

Is there a way to provide a fake window.location.hrefstring, 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:

  1. 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.

  2. When you want to prevent a specific method from being called directly (possibly because it triggers undesired behavior, such as a XMLHttpRequest or similar).

什么时候使用存根?

需要时使用存根:

  1. 从测试中控制方法的行为以强制代码沿特定路径运行。示例包括强制方法抛出错误以测试错误处理。

  2. 当您想阻止直接调用特定方法时(可能是因为它触发了不希望的行为,例如 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()调用。您的代码中存在另一个错误:第三个参数必须是函数,而不是其他类型的值。这是一个回调,而不是属性应该返回的内容。

See the source code of stub()

查看源代码 stub()

回答by KhaledMohamedP

You need to use globalto mock the windowobject for your test in beforeEachor it

您需要使用global嘲笑的window对象为您的测试中beforeEachit

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 assignmethod on the window.locationobject.

使用window.location.assign(url)而不是覆盖 的值window.location。然后你可以assignwindow.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 的回复