Sinon: ES5ゲッターとセッターをラップします

作成日 2012年03月03日  ·  23コメント  ·  ソース: sinonjs/sinon

var o = {
  get foobar() { return 'foobar' },
  set foobar(s) { throw 'bzzt!' },
  foo: function() { return 'foo' },
  bar: 'bar'
}; // -> { foobar: [Getter/Setter], foo: [Function], bar: 'bar' }

sinon.mock(o).expects('foobar').returns('woohoo'); // doesn't because sinon.wrapMethod() does an object[property] which accesses the getter which returns a string

ゲッターとセッターをサポートするには、オブジェクトに対してObject.getOwnPropertyDescriptor(obj, prop)を実行し、存在しない場合は再帰的なObject.getPrototypeOf(obj)する必要があります。記述子には、 'get''set'それらが定義されている

しかし、ゲッターだけ、セッターだけ、またはその両方をモックアウトしたい場合があるので、それをどのように指定しますか? いくつかのオプション:

mock(o).expects('foobar'); // ambiguous, the setter? getter? or both?
mock(o).expects('get foobar'); // ambiguous, there may be a legitimate property named "get foobar"
mock(o).expectsGet('foobar'); // clear but more code in Sinon and more to document ?
mock(o).expectsSet('foobar'); // ditto

また、現在の環境には存在しない可能性のある機能を処理するための規則がすでに用意されていますか? 誰かがIE6でこれを行おうとすると、どうなりますか?

最も参考になるコメント

珍しいことではない1つのユースケースは、ゲッターが提供されているがセッターが提供されていない場合です。これにより、プロパティが読み取り専用になります。これは、実稼働コードには適していますが、テストの邪魔になります。 Sinonにゲッターとセッターをサポートさせることは、そのユースケースに話しかけるでしょう。

全てのコメント23件

あなたの例を見ると、ゲッターをモックすることが良いテスト方法であるかどうかは完全にはわかりません-テスト期間中にプロパティをある値に設定するだけで、ほとんどの場合大いに役立つと思います(?)

とにかく、スタブが関数ではなくオブジェクトである場合、それはプロパティ記述子として扱われますか? 何かのようなもの:

stub(o, "foobar", { get: function () { return 42; } });

しかし、あなたの期待をどのように解決するかはわかりません。 しかし、私が言ったように-しかし、プロパティのルックアップに偽の期待を置くことは価値がありますか? あなたがそれを必要とするならば、多分それらは代わりに「実際の」方法であるべきであると私には思えますか?

例は単純でした。 私がこれを実行しようとしていた実際のコードはget identifierと呼ばれ、いくつかのものを一緒に追加しました。そのうちのいくつかは、テストで気にしたくない場所からのものでした。確認したかっただけです。 x.identifierがアクセスされ、返される内容を制御できます。 今のところ私はgetIdentifier()を使用しますが、これは問題ありませんが、計算されたプロパティのゲッターとセッターが将来的に増える可能性があることを考えると、これはSinonが処理できる/すべきである可能性がありますか?

これについてはまだ未定です。 しばらく休ませて後で決めます。 より多くの入力/提案がある場合は、ここにそれらを書き留めてください。

珍しいことではない1つのユースケースは、ゲッターが提供されているがセッターが提供されていない場合です。これにより、プロパティが読み取り専用になります。これは、実稼働コードには適していますが、テストの邪魔になります。 Sinonにゲッターとセッターをサポートさせることは、そのユースケースに話しかけるでしょう。

とりあえず、シノンでゲッターやセッターをサポートする価値はないと思います。

明らかに、この問題が議論されてからしばらく経ちましたが、この機能は非常に役立ちます...

+1
私もそれが恋しいです。 これは、ファイルやデータベースオブジェクトなど、基礎となるリソースに対するゲッターを使用した抽象化として機能するコンポーネントで使用する場合に特に役立ちます。 それらのゲッターをスタブできるといいでしょう。

また、これが再開されることを望んでいます。 これは、ラップされたロケーションオブジェクトのフィールドをスタブ化する場合に特に役立ちます。

その機能の+1!

:+1:私もこの機能の必要性を感じました。

:+1:これを再度開く必要があります。 特にES6が普及しているため、これはこれまで以上に重要です。 expectsGetバリアントが好きです。

+1私は@simonzackに心から同意し

+1

また、これが再開されることを望んでいます。 これは、ラップされたロケーションオブジェクトのフィールドをスタブ化する場合に特に役立ちます。

https://github.com/mroderick/wrappleはあなたのためにそのギャップを埋めますか?

最近はラップルをかなり多用しているので、この問題についてコメントするのを忘れていました。 それはおそらくあなたが言うようにラップルがギャップを埋めたことを意味します。

+1は、ゲッターのモックをサポートしていないシノンに遭遇しました

こんにちは@derwaldgeist 、あなたはシノンの最新バージョンを使用していますか?

最新のものは、 sandboxessinon.stub両方でスタブゲッターをサポートします。

あなたがしなければならないのは、たとえば、 get関数を使用することだけです。

var myObj = {
    prop: "foo"
};

createStub(myObj, "prop").get(function getterFn() {
    return "bar";
});

myObj.prop // "bar"

これがあなたのユースケースに適しているかどうか、またはさらに疑問がある場合はお知らせください。

早く戻ってきてくれてありがとう。
しかし、そのように定義されたゲッターを復元する方法が見つかりませんでしたか? 私はsinonのソースコードを見ても、get()を呼び出すときに元のゲッターを格納するメカニズムを見つけることができませんでした。

こんにちは@derwaldgeist

スタブされる前に未定義であったとしても、ゲッターを復元することは確かに可能です。 作成したスタブでrestoreメソッドを呼び出すだけです。次に例を示します。

var myObj = {
    prop: "foo"
};

var stub = createStub(myObj, "prop");

stub.get(function getterFn() {
    return "baz";
});

myObj.prop // "baz"

stub.restore();

myObj.prop // "foo"

このrestoreメソッドをstubメソッド自体(非関数プロパティをスタブする場合)またはwrapMethodユーティリティに追加し

うわー、それは速かった。 私はこれを試しました:

 const stub = sinon.stub(myObj, 'prop');
 stub.get(() => ({}));
  ...
 stub.restore();

しかし、restore()を実行すると、次のように表示されます: Cannot redefine property: prop

createStubメソッドはどこから来たのですか?

@derwaldgeistテストから取得しました。申し訳ありませんが、編集するのを忘れました。 とにかく、それはsinon.stubと同じです。

確認できるように、使用しているシノンのバージョンを教えてください。

configurable: trueなしで定義されているためにプロパティを復元できず、記述子を変更できなかったバグを修正した最新バージョンをまだ使用していない可能性があります。

@derwaldgeistと同じように表示されます。 私はv4を使用していると思いますが、他のいくつかの部門がv1.7を使用していたため、どちらが実際に使用されているのかわかりません。 実行時に確認できるsinon.versionが表示されませんでした。

@ jshado1現在使用しているメジャーバージョンを知りたい場合は、変更ログまたは移行ガイドを参照して、重大な変更をテストできます。 バージョン4の場合、 sinon.stub({}, 'nonExistingProperty')スローすることを表明できます

このページは役に立ちましたか?
0 / 5 - 0 評価