5

window.location.searchを呼び出す単純な関数をテストしようとしています。選択したURLを返すことができるように、この呼び出しをスタブする方法を理解しようとしています。

働き:

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

もちろん、これは機能しません。スタブを正しく指定しているとは思いませんが、それは私の意図を示しています。

これを解決する方法についてのアイデアは大歓迎です。

4

2 に答える 2

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

私の通常のJavascriptの経験と同じです。実用的な解決策は、そこにたどり着くまでの道のりほど苦痛ではありませんでした。コメントと貢献をありがとうございました。

于 2012-08-15T15:20:07.233 に答える
2

更新: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")
于 2012-08-14T20:50:29.660 に答える