プロパティを監視する

プロパティは関数より複雑です。Jasmine では、関数スパイでできることはプロパティスパイでもできますが、異なる構文を使用する必要があります。

getter または setter スパイを作成するには、spyOnProperty を使用します。

it("allows you to create spies for either type", function() {
  spyOnProperty(someObject, "myValue", "get").and.returnValue(30);
  spyOnProperty(someObject, "myValue", "set").and.callThrough();
});

既存のスパイの値を変更するのは、関数のスパイの場合よりも困難です。getter メソッドを呼び出さずにプロパティを参照することはできないためです。これを回避するには、後からの変更のためにスパイへの参照を保存できます。

beforeEach(function() {
  this.propertySpy = spyOnProperty(someObject, "myValue", "get").and.returnValue(1);
});

it("lets you change the spy strategy later", function() {
  this.propertySpy.and.returnValue(3);
  expect(someObject.myValue).toEqual(3);
});

スパイへの参照の保存が面倒な場合は、Object.getOwnPropertyDescriptor を使用してテストのどこからでもアクセスできます。

beforeEach(function() {
  spyOnProperty(someObject, "myValue", "get").and.returnValue(1);
});

it("lets you change the spy strategy later", function() {
  Object.getOwnPropertyDescriptor(someObject, "myValue").get.and.returnValue(3);
  expect(someObject.myValue).toEqual(3);
});

createSpyObj にプロパティの配列またはハッシュを第 3 引数として渡すことで、複数のプロパティを持つスパイオブジェクトをすばやく作成できます。この場合、作成されたスパイへの参照がないので、後でスパイ戦略を変更する必要がある場合は、Object.getOwnPropertyDescriptor アプローチを使用する必要があります。

it("creates a spy object with properties", function() {
  let obj = createSpyObj("myObject", {}, { x: 3, y: 4 });
  expect(obj.x).toEqual(3);

  Object.getOwnPropertyDescriptor(obj, "x").get.and.returnValue(7);
  expect(obj.x).toEqual(7);
});