2012-08-14 9 views
5

Ich versuche eine einfache Funktion zu testen, die einen Aufruf von window.location.search aufruft. Ich versuche zu verstehen, wie ich diesen Anruf stumm mache, damit ich eine URL meiner Wahl zurückgeben kann.sinon stub für window.location.search

Funktion:

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, " ")) 

Testfall:

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) 

Mein ursprünglicher Versuch, einen Wert direkt wie so zurück war:

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

Dies ist natürlich nicht Arbeit. Ich glaube nicht, dass ich den Stub korrekt spezifiziere, aber er zeigt meine Absicht.

Irgendwelche Ideen auf, wie man das löst, würde sehr geschätzt werden.

Antwort

6

So, wie bereits erwähnt, können Sie nicht direkt Mock window.location. Die Wrapper-Idee von mylib.search hat auch nicht mit meiner Situation funktioniert. Also, was ich getan habe, war mein Ruf nach window.location.search in seine eigene Funktion auszubrechen. Meine neue Klasse sieht so aus:

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 

Da ist in meinem Testfall, ich die Funktion mit meinem Test-Code zu ersetzen, wie so:

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") 

Für diejenigen, die Coffee nicht lesen, das äquivalent javascript Code ist unten aufgeführt:

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); 
}); 

Wie ist meine übliche Erfahrung mit Javascript. Die Arbeitslösung war nicht annähernd so schmerzhaft wie die Reise dorthin. Vielen Dank für Ihre Kommentare und Beiträge.

2

UPDATE: window.location, so scheint es, ist ein bisschen ein Sonderfall, siehe diese Diskussion: https://groups.google.com/forum/?fromgroups#!topic/sinonjs/MMYrwKIZNUU%5B1-25%5D

Der einfachste Weg, dieses Problem zu lösen, ist eine Wrapper-Funktion um window.location und Stummel zu schreiben, die:

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

Und im Test:

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

ORIGINAL ANTWORT:

Versuchen Sie folgendes:

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

Ich habe das schon einmal ausprobiert und habe es gerade noch einmal ausprobiert: 'TypeError: Versuch, die Stringeigenschaftssuche als Funktion zu umbrechen' –

+0

oh sorry,' window.location.search' ist eine Zeichenkette, keine Funktion, also kannst du Mach es nicht aus. Ersetzen Sie den Stub durch eine Zuweisung: 'window.location.search =" myUrl "'. –

+0

Seltsam, die Durchführung einer console.log vor und nach einer leeren Zeichenfolge, so dass ich nicht sicher bin, was los ist. Die Aufgabe bleibt nicht hängen. Ich habe meinen Code aktualisiert, um auch meinen Testfall zu zeigen. –