2012-08-14 61 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