11

Mocha テストで依存関係をスタブ化する方法として、sinon.js を使用しています。私は古典的なモック アプローチよりも「スパイ」アプローチを好みます。なぜなら、スパイの内省はより明確に見え、古典的なモック オブジェクトを使用したやや後ろ向きな考え方よりも柔軟性が高いからです。

とはいえ、オブジェクト全体のテスト スパイを作成する場合、間違った使い方をしているのではないでしょうか。4 つのメソッドを持つテスト依存関係があり、それらの各メソッドをスタブ化し、そのうちの 1 つまたは 2 つに対してアサーションを作成したいとします。現在、私はこれをやっています:

var spyObj = {
  aMethod: sinon.spy(),
  otherMethod: sinon.spy(),
  whatever: sinon.spy()
};

それから私はただのようなことを尋ねますspyObj.aMethod.calledWith(a, b, c)

テストスイート自体でメソッドの名前を繰り返すよりも、クラス全体をモックアウトするより良い方法はありますか? sinon.stub() が特定のオブジェクトのすべてのメンバーを反復しようとしているように見えますが、V8 などの最新の JS ランタイムでは、オブジェクトが実際には列挙可能なものです。また、同等のオブジェクトを返すのではなく、実際のオブジェクトにモンキー パッチを適用しようとしますが、これはやや望ましくありません。インターフェイスに準拠しているが、特に指定しない限り、null オブジェクトのように動作するオブジェクトが必要なだけです。

次のようなことができるとよいでしょう:

var spyObject = sinon.spy(MyClass.prototype);

上記のようなラッパーを作成するために、Node.js でコンストラクター/プロトタイプのすべてのメソッドを見つけるにはどうすればよいですか?

これは、多くのメソッドで呼び出しをテストすることよりも、ロジックをスタブ化することに関するものです (1 つに制限するか、プッシュで 2 つに制限しようとしています)。たとえば、不要な I/O を実行したり、実行した場合に追加の複雑なフィクスチャが必要になったりする可能性があります。

4

2 に答える 2

7

これを行う方法を見つけました:

/** Accept a prototype and return a full stub object */
function stub(obj, target) {
  var cls = (typeof obj == 'function') ? obj.prototype : obj;
  target = target || {};

  Object.getOwnPropertyNames(cls).filter(function(p){
    return typeof cls[p] == 'function';
  }).forEach(function(p) { target[p] = sinon.stub() });

  return cls.__proto__ ? stub(cls.__proto__, target) : target;
};

次のように使用します。

var response = stub(http.ServerResponse);
response.getHeader.withArgs('X-Foo').returns('bob');
response.getHeader.withArgs('X-Bar').returns('barry');

console.log(response.getHeader('X-Foo')); // bob
console.log(response.getHeader('X-Bar')); // barry
于 2012-08-20T12:12:48.773 に答える