ジャスミンを使用してコンストラクターをスパイします
-
27-10-2019 - |
質問
私はジャスミンを使用して、特定のオブジェクトが作成され、メソッドが呼び出されたかどうかをテストしています。
FlipCounterオブジェクトを作成し、それらにSetValueメソッドを呼び出すjQueryウィジェットがあります。 FlipCounterのコードはこちらです: https://bitbucket.org/cnanney/apple-style-flip-counter/src/13fd00129a41/js/flipcounter.js
flipcountersは以下を使用して作成されます。
var myFlipCounter = new flipCounter("counter", {inc: 23, pace: 500});
FlipCountersが作成され、SetValueメソッドがそれらに呼び出されることをテストしたいと思います。私の問題は、これらのオブジェクトが作成される前であっても、これらのオブジェクトをどのようにスパイするかということです。コンストラクターをスパイし、偽のオブジェクトを返しますか?サンプルコードは本当に役立ちます。ご協力いただきありがとうございます! :)
アップデート:
私はこのようなフリップカウンターでスパイを試みました:
myStub = jasmine.createSpy('myStub');
spyOn(window, 'flipCounter').andReturn(myStub);
//expectation
expect(window.flipCounter).toHaveBeenCalled();
次に、FlipCounterによるSetValue Callのテスト:
spyOn(myStub, 'setValue');
//expectation
expect(myStub.setValue).toHaveBeenCalled();
FlipCounterを初期化するための最初のテストは問題ありませんが、SetValue呼び出しをテストするために、私が取得しているのは「setValue()メソッドが存在しない」エラーだけです。私はこれを正しい方法でやっていますか?ありがとう!
解決
flipCounter
オブジェクトを構築する場合でも、単なる関数です。したがって、あなたはできます:
var cSpy = spyOn(window, 'flipCounter');
スパイを取得し、あらゆる種類の検査を行うか、次のように言ってください。
var cSpy = spyOn(window, 'flipCounter').andCallThrough();
var counter = flipCounter('foo', options);
expect(cSpy).wasCalled();
しかし、これはやり過ぎのようです。それだけで十分でしょう:
var myFlipCounter = new flipCounter("counter", options);
expect(myFlipCounter).toBeDefined();
expect(myFlipCounter.getValue(foo)).toEqual(bar);
他のヒント
使用することをお勧めします jasmine.createSpyObj()
スパイする必要があるプロパティでオブジェクトをモックしたい場合。
myStub = jasmine.createSpyObj('myStub', ['setValue']);
spyOn(window, 'flipCounter').andReturn(myStub);
これにより、予想される相互作用がテストされます flipCounter
インターフェイス、に依存することなく flipCounter
実装。
以下は「ウィンドウ」に依存していません。これがテストしたいコードだとしましょう -
function startCountingFlips(flipCounter) {
var myFlipCounter = new flipCounter("counter", {inc: 23, pace: 500});
}
あなたのテストは -
var initSpy = jasmine.createSpy('initFlipCounter');
var flipCounter = function(id, options) {
initSpy(id, options);
}
startCountingFlips(flipCounter);
expect(initSpy).toHaveBeenCalledWith("counter", {inc:23, pace:500});
偽のコンストラクターを実装する必要があります flipCounter
それが設定されます setValue
スパイ機能へのプロパティ。テストしたい関数は次のとおりです。
function flipIt() {
var myFlipCounter = new flipCounter("counter", {inc: 23, pace: 500});
myFlipCounter.setValue(100);
}
あなたのスペックは次のようになるはずです:
describe('flipIt', function () {
var setValue;
beforeEach(function () {
setValue = jasmine.createSpy('setValue');
spyOn(window, 'flipCounter').and.callFake(function () {
this.setValue = setValue;
});
flipIt();
});
it('should call flipCounter constructor', function () {
expect(window.flipCounter)
.toHaveBeenCalledWith("counter", {inc: 23, pace: 500});
});
it('should call flipCounter.setValue', function () {
expect(setValue).toHaveBeenCalledWith(100);
});
});
コンストラクターをテストする私のバージョンは、プロトタイプをスパイすることです。
spyOn(flipCounter.prototype, 'setValue').and.callThrough();
var myFlipCounter = new flipCounter("counter", {inc: 23, pace: 500});
expect(flipCounter.prototype.setValue).toHaveBeenCalledTimes(1);
ジャスミンモックを使用してこれを行う方法がわからないが、強力なモッキング/スパイ/スタブが必要な場合はお勧めします Sinon.js, 、ウィッチはジャスミンと非常にうまく機能します。
ドキュメントから:
テストスパイは、引数、返品値、この値の値、およびすべての呼び出しに対してスローされた例外(もしあれば)を記録する関数です。テストスパイは、匿名の関数であるか、既存の関数をラップすることができます。
模擬(および模擬期待)は、事前にプログラムされた動作(スタブなど)と事前にプログラムされた期待を備えた偽の方法(スパイなど)です。模擬は、予想どおりに使用されていない場合、テストに失敗します。
Sinon.jsを使用すると、別のスパイを返すFlipcounterコンストラクターの模擬を作成できます。
次に、コンストラクターがconstructormock.calledwithnew()を使用して呼び出されたと主張し、返されたスパイがreturnedspy.calledwith(arg1、arg2 ...)で呼び出されたと主張します。