web-dev-qa-db-ja.com

別のメソッド内で作成されたオブジェクトでJasmineスパイを使用する方法

次のコードスニペットが与えられた場合、spyOnを実行するとdoSomethingが呼び出されることを確認する JasmineMyFunctionテストをどのように作成しますか?

function MyFunction() {
    var foo = new MyCoolObject();
    foo.doSomething();
};

これが私のテストの様子です。残念ながら、spyOn呼び出しを評価するとエラーが発生します。

describe("MyFunction", function () {
    it("calls doSomething", function () {

        spyOn(MyCoolObject, "doSomething");
        MyFunction();
        expect(MyCoolObject.doSomething).toHaveBeenCalled();

    });
});

その時点では、JasmineはdoSomethingメソッドを認識していないようです。助言がありますか?

17

new MyCoolObject()を呼び出すと、MyCoolObject関数が呼び出され、関連するプロトタイプを持つ新しいオブジェクトが取得されます。これは、spyOn(MyCoolObject, "doSomething")を実行すると、new呼び出しによって返されたオブジェクトにスパイを設定するのではなく、doSomething関数自体に可能なMyCoolObject関数を設定することを意味します。

あなたは次のようなことができるはずです:

it("calls doSomething", function() {
  var originalConstructor = MyCoolObject,
      spiedObj;
  spyOn(window, 'MyCoolObject').and.callFake(function() {
    spiedObj = new originalConstructor();
    spyOn(spiedObj, 'doSomething');
    return spiedObj;
  });
  MyFunction();
  expect(spiedObj.doSomething).toHaveBeenCalled();
});
17
Gregg

あるいは、グレッグが示唆したように、「プロトタイプ」で作業することもできます。つまり、MyCoolObjectを直接スパイする代わりに、MyCoolObject.prototypeをスパイすることができます。

describe("MyFunction", function () {
    it("calls doSomething", function () {
        spyOn(MyCoolObject.prototype, "doSomething");
        MyFunction();
        expect(MyCoolObject.prototype.doSomething).toHaveBeenCalled();

    });
});
21
hyong