web-dev-qa-db-ja.com

Jasmineで(メソッドではなく)値プロパティをspyOnする方法

JasmineのspyOnはメソッドの動作を変更するのに適していますが、オブジェクトの(メソッドではなく)値のプロパティを変更する方法はありますか?コードは次のようになります。

spyOn(myObj, 'valueA').andReturn(1);
expect(myObj.valueA).toBe(1);
90
Shuping

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ソースコードの行を次に示します。

https://github.com/jasmine/jasmine/blob/7f8f2b5e7a7af70d7f6b629331eb6fe0a7cb9279/src/core/requireInterface.js#L199

ジャスミン2.6.1で元の質問に答えると、次のようになります。

const spy = spyOnProperty(myObj, 'valueA', 'get').andReturn(1);
expect(myObj.valueA).toBe(1);
expect(spy).toHaveBeenCalled();
77
Juan

Jasmineにはその機能はありませんが、Object.definePropertyを使用して何かを一緒にハッキングできる場合があります。

ゲッター関数を使用するようにコードをリファクタリングしてから、ゲッターをスパイできます。

spyOn(myObj, 'getValueA').andReturn(1);
expect(myObj.getValueA()).toBe(1);
12
Eric

オブジェクト上で直接変更できない理由はありますか? javascriptがオブジェクトのプロパティの可視性を強制するようなものではありません。

9
Paul Harris

最良の方法は、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オブジェクトのgetclientWidthを設定しています。

6
Aniruddha Das

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');
3
Martin

私は剣道グリッドを使用しているため、実装をゲッターメソッドに変更することはできませんが、これをテストし(グリッドをモックする)、グリッド自体をテストしません。私はスパイオブジェクトを使用していましたが、これはプロパティのモックをサポートしていませんので、これを行います:

    this.$scope.ticketsGrid = { 
        showColumn: jasmine.createSpy('showColumn'),
        hideColumn: jasmine.createSpy('hideColumn'),
        select: jasmine.createSpy('select'),
        dataItem: jasmine.createSpy('dataItem'),
        _data: []
    } 

少し長い曲がりくねっていますが、うまくいきます

1
jolySoft

これを行う正しい方法は、spy onプロパティを使用することです。これにより、特定の値を持つオブジェクトのプロパティをシミュレートできます。

const spy = spyOnProperty(myObj, 'valueA').and.returnValue(1);
expect(myObj.valueA).toBe(1);
expect(spy).toHaveBeenCalled();
1
alexalejandroem

テストが必要なこのようなメソッドがあるとします。小さな画像の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で動作する可能性があります

1
Vorsprung

ここでのパーティーには少し遅れていますが、

呼び出しオブジェクトに直接アクセスでき、各呼び出しの変数を取得できます

expect(spy.calls.argsFor(0)[0].value).toBe(expectedValue)
0
CosmicChild