JasmineのspyOn
はメソッドの動作を変更するのに適していますが、オブジェクトの(メソッドではなく)値のプロパティを変更する方法はありますか?コードは次のようになります。
spyOn(myObj, 'valueA').andReturn(1);
expect(myObj.valueA).toBe(1);
2017年2月に、この機能を追加するPRをマージし、2017年4月にリリースしました。
使用するゲッター/セッターをスパイするために:const spy = spyOnProperty(myObj, 'myGetterName', 'get');
ここでmyObjはインスタンスで、 'myGetterName'はクラスでget myGetterName() {}
として定義されたものの名前であり、3番目のパラメーターはget
またはset
型です。
spyOn
で作成されたスパイで既に使用しているのと同じアサーションを使用できます。
たとえば、次のことができます。
const spy = spyOnProperty(myObj, 'myGetterName', 'get'); // to stub and return nothing. Just spy and stub.
const spy = spyOnProperty(myObj, 'myGetterName', 'get').and.returnValue(1); // to stub and return 1 or any value as needed.
const spy = spyOnProperty(myObj, 'myGetterName', 'get').and.callThrough(); // Call the real thing.
興味がある場合にこのメソッドを使用できるgithubソースコードの行を次に示します。
ジャスミン2.6.1で元の質問に答えると、次のようになります。
const spy = spyOnProperty(myObj, 'valueA', 'get').andReturn(1);
expect(myObj.valueA).toBe(1);
expect(spy).toHaveBeenCalled();
Jasmineにはその機能はありませんが、Object.defineProperty
を使用して何かを一緒にハッキングできる場合があります。
ゲッター関数を使用するようにコードをリファクタリングしてから、ゲッターをスパイできます。
spyOn(myObj, 'getValueA').andReturn(1);
expect(myObj.getValueA()).toBe(1);
オブジェクト上で直接変更できない理由はありますか? javascriptがオブジェクトのプロパティの可視性を強制するようなものではありません。
最良の方法は、spyOnProperty
を使用することです。 3つのパラメーターが必要であり、get
またはset
を3番目のパラメーターとして渡す必要があります。
const div = fixture.debugElement.query(By.css('.Ellipsis-overflow'));
// now mock properties
spyOnProperty(div.nativeElement, 'clientWidth', 'get').and.returnValue(1400);
spyOnProperty(div.nativeElement, 'scrollWidth', 'get').and.returnValue(2400);
ここでは、div.nativeElement
オブジェクトのget
のclientWidth
を設定しています。
ES6(Babel)またはTypeScriptを使用している場合は、getおよびsetアクセサーを使用してプロパティをスタブできます
export class SomeClassStub {
getValueA = jasmine.createSpy('getValueA');
setValueA = jasmine.createSpy('setValueA');
get valueA() { return this.getValueA(); }
set valueA(value) { this.setValueA(value); }
}
次に、テストでプロパティが設定されていることを確認できます:
stub.valueA = 'foo';
expect(stub.setValueA).toHaveBeenCalledWith('foo');
私は剣道グリッドを使用しているため、実装をゲッターメソッドに変更することはできませんが、これをテストし(グリッドをモックする)、グリッド自体をテストしません。私はスパイオブジェクトを使用していましたが、これはプロパティのモックをサポートしていませんので、これを行います:
this.$scope.ticketsGrid = {
showColumn: jasmine.createSpy('showColumn'),
hideColumn: jasmine.createSpy('hideColumn'),
select: jasmine.createSpy('select'),
dataItem: jasmine.createSpy('dataItem'),
_data: []
}
少し長い曲がりくねっていますが、うまくいきます
これを行う正しい方法は、spy onプロパティを使用することです。これにより、特定の値を持つオブジェクトのプロパティをシミュレートできます。
const spy = spyOnProperty(myObj, 'valueA').and.returnValue(1);
expect(myObj.valueA).toBe(1);
expect(spy).toHaveBeenCalled();
テストが必要なこのようなメソッドがあるとします。小さな画像のsrc
プロパティをチェックする必要があります
function reportABCEvent(cat, type, val) {
var i1 = new Image(1, 1);
var link = getABC('creosote');
link += "&category=" + String(cat);
link += "&event_type=" + String(type);
link += "&event_value=" + String(val);
i1.src = link;
}
以下のspyOn()は、テストから偽のコードを「新しいイメージ」に与えます。spyOnコードは、srcプロパティのみを持つオブジェクトを返します。
変数 "hook"は、SpyOnの偽のコードで、そして後で "reportABCEvent"が呼び出された後に見えるようにスコープされているため
describe("Alphabetic.ads", function() {
it("ABC events create an image request", function() {
var hook={};
spyOn(window, 'Image').andCallFake( function(x,y) {
hook={ src: {} }
return hook;
}
);
reportABCEvent('testa', 'testb', 'testc');
expect(hook.src).
toEqual('[zubzub]&arg1=testa&arg2=testb&event_value=testc');
});
これはジャスミン1.3用ですが、「andCallFake」が2.0の名前に変更されると2.0で動作する可能性があります
ここでのパーティーには少し遅れていますが、
呼び出しオブジェクトに直接アクセスでき、各呼び出しの変数を取得できます
expect(spy.calls.argsFor(0)[0].value).toBe(expectedValue)