2012-08-14 25 views
5

我想测试一个调用window.location.search的简单函数。我试图了解如何存根这个电话,以便我可以返回我选择的网址。sinon stub for window.location.search

功能:

getParameterByName: (name) =>  
    name = name.replace(/[\[]/, "\\\[").replace(/[\]]/, "\\\]") 
    regexS = "[\\?&]" + name + "=([^&#]*)" 
    regex = new RegExp(regexS)  
    results = regex.exec(window.location.search) //Stub call to window.location.search 
    if(results == null) 
    return "" 
    else 
    return decodeURIComponent(results[1].replace(/\+/g, " ")) 

测试用例:

describe "Data tests",() -> 
    it "Should parse parameter from url",() ->   
    data = new Data() 

    console.log("search string: " + window.location.search) //prints "search string:" 
    window.location.search = "myUrl" 
    console.log("search string: " + window.location.search) //prints "search string:" 
    console.log(data.getParameterByName('varName')) 

    expect(true).toBe(true) 

我最初的尝试是直接返回一个值,像这样:

sinon.stub(window.location.search).returns("myUrl") 

这当然,不工作。我不认为我正确地指定了存根,但它显示了我的意图。

任何想法如何解决这将不胜感激。

回答

6

因此,正如前面提到的,你不能模拟window.location的直接。 mylib.search包装理念也不适用于我的情况。所以,我所做的就是打电话给window.location.search进入自己的功能。我的新类看起来像这样:

getParameterByName: (name) => 
    console.log("name: #{name}") 
    name = name.replace(/[\[]/, "\\\[").replace(/[\]]/, "\\\]") 
    regexS = "[\\?&]" + name + "=([^&#]*)" 
    regex = new RegExp(regexS) 
    results = regex.exec(@getWindowLocationSearch()) 
    if(results == null) 
    return "" 
    else 
    return decodeURIComponent(results[1].replace(/\+/g, " ")) 

getWindowLocationSearch:() => 
    window.location.search 

然后在我的测试情况下,我与我的测试代码替换功能,像这样:

describe "Data tests",() -> 
    it "Should parse parameter from localhost url",() -> 
    goodUrl = "http://localhost:3333/?token=val1" 

    Data::getWindowLocationSearch =() -> return goodUrl 
    unit = new Data() 
    result = unit.getParameterByName("token") 

    expect(result).toBe("val1") 

对于那些谁不读的CoffeeScript,等效的javascript代码如下:

it("Should parse parameter from localhost url", function() { 
    var goodUrl, result, unit; 
    goodUrl = "http://localhost:3333/?token=val1"; 
    Data.prototype.getWindowLocationSearch = function() { 
    return goodUrl; 
    }; 
    unit = new Data(); 
    result = unit.getParameterByName("token"); 
    expect(result).toBe("val1"); 
    return expect(true).toBe(true); 
}); 

正如我平时的使用经验。工作解决方案不像到达那里的旅程那么痛苦。非常感谢您的意见和贡献。

2

UPDATE:window.location,似乎是有点特殊的情况下,看到这个讨论:https://groups.google.com/forum/?fromgroups#!topic/sinonjs/MMYrwKIZNUU%5B1-25%5D

来解决这个问题,最简单的方法是写一个包装函数周围window.location和存根:

mylib.search = function (url) { 
    window.location.search = url; 
}; 

并在测试:

sinon.stub(mylib, 'search').returns("myUrl") 

原来的答案:

试试这个:

sinon.stub(window.location, 'search').returns("myUrl") 
+1

我试过之前,我只是试过一遍:'TypeError:试图包装字符串属性搜索作为函数' – 2012-08-14 21:16:16

+0

哦对不起,'window.location.search'是一个字符串不是一个函数,所以你可以不存在。将该存根替换为一个赋值:'window.location.search =“myUrl”'。 – 2012-08-14 21:24:38

+0

奇怪的是,在执行一个console.log之前和之后导致一个空字符串,所以我不知道发生了什么。这项任务并不坚持。我更新了我的代码以显示我的测试用例。 – 2012-08-14 22:05:33