55

私は、sinonを使用してコンストラクターをモックする方法を理解しようとして髪を引っ張っています。いくつかの引数を受け入れるコンストラクターを呼び出すことで、複数のウィジェットを作成する関数があります。コンストラクターが正しいパラメーターで正しい回数呼び出されることを確認したいのですが、実際にウィジェットを作成したくありません。次のリンクは、コンストラクターをモックする簡単な方法を説明しているように見えますが、私には機能しません。

Jasmineを使用してコンストラクターをスパイする

http://tinnedfruit.com/2011/03/25/testing-backbone-apps-with-jasmine-sinon-2.html

コンストラクターをスタブするために次の呼び出しを行うと、次のようになります。

sinon.stub(window, "MyWidget");

次のエラーが発生します。

Uncaught TypeError: Attempted to wrap undefined property MyWidget as function 

Chromeでデバッグすると、スコープ変数のローカルセクションにMyWidgetが表示されますが、ウィンドウの外にMyWidgetプロパティがありません。

どんな助けでも大歓迎です。

4

9 に答える 9

24

私のコードは新しい演算子を呼び出していたので、これに対する解決策が必要でした。新しい呼び出しで作成されたオブジェクトをモックしたかったのです。

var MockExample = sinon.stub();
MockExample.prototype.test = sinon.stub().returns("42");
var example = new MockExample();
console.log("example: " + example.test()); // outputs 42

次に、rewireを使用して、テストしていたコードに挿入しました。

rewiredModule = rewire('/path/to/module.js');
rewiredModule.__set__("Example", example);
于 2015-11-19T16:48:31.210 に答える
8

sinonjsの公式サイトから:

object.methodをスタブ関数に置き換えます。元の関数は、object.method.restore();を呼び出すことで復元できます。(またはstub.restore();)。プロパティがすでに関数でない場合は例外がスローされ、メソッドをスタブするときのタイプミスを回避します。

これは、スタブを作成する関数がオブジェクトオブジェクトのメンバーである必要があることを示しています。

物事を明確にするために; あなたが呼ぶ

sinon.stub(window, "MyWidget");

MyWidget関数はグローバルスコープ内にある必要があります(ウィンドウをパラメーターとして渡すため)。ただし、すでに述べたように、この関数はローカルスコープにあります(おそらくオブジェクトリテラルまたは名前空間内で定義されています)。

javascriptでは、誰もがグローバルスコープにアクセスできますが、その逆はできません。

MyWidget関数を宣言する場所を確認し、コンテナオブジェクトを最初のパラメータとしてsinon.stub()に渡します。

于 2013-01-28T21:12:46.363 に答える
6

Sinon 4.4.2を使用して、次のようなインスタンスメソッドをモックすることができました。

const testObj = { /* any object */ }
sinon.stub(MyClass.prototype, "myMethod").resolves(testObj)
let myVar = await new MyClass(token).myMethod(arg1, arg2)
// myVar === testObj

ここで提供される同様のソリューション: Sinon.jsを使用したクラスメソッドのスタブ

于 2018-07-12T22:26:55.073 に答える
2

Mockeryを使用して、コンストラクター/関数を問題なくモックしました。

var mockery = require('mockery');
var sinon = require('sinon');

mockery.enable({
  useCleanCache: true,
  warnOnReplace: false,
  warnOnUnregistered: false
});

exports.Client = function() {/* Client constructor Mock */};
var ClientSpy = sinon.spy(exports, 'Client');
mockery.registerMock('Client', ClientSpy);

var Factory = require('Factory'); // this module requires the Client module

上記の例と同じように、SinonSpyを適用できるはずです。

テスト後にMockeryを無効にするかリセットしてください!

于 2015-04-17T17:39:02.807 に答える
2

を使用するsinon.createStubInstance(MyES6ClassName)と、MyES6ClassNameがnewキーワードで呼び出されると、MyES6ClassNameインスタンスのスタブが返されます。

于 2019-06-11T09:36:20.907 に答える
0

ドキュメントでこれを見つけました。

MyConstructorのスタブオブジェクトを作成したいが、コンストラクターを呼び出さない場合は、このユーティリティ関数を使用します。

varスタブ=sinon.createStubInstance(MyConstructor)

于 2015-06-04T14:18:36.640 に答える
0

sinon.stub.throws(expectedErr)ではなく誤って入力して、このエラーが発生しましたsinon.stub().throws(expectedErr)。私は以前に同様の間違いを犯したことがあり、この特定のメッセージに遭遇したことがないので、それは私を投げました。

于 2017-02-12T00:52:06.897 に答える
0

コンストラクターをsinonでモックしてスタブ化する

私は2つの解決策を示します。1つ目は、コンストラクターを動作でモックする方法という質問に対処し、2つ目は、ダミーでコンストラクターをスタブ化する方法を示しています。グーグルはそれをスタブする方法を検索するためにこの質問に何度も私を導きました。

コンストラクターを動作でモックする

これが最短経路かどうかはわかりません。少なくとも、求められていたものはそうです。

まず、sinonのfakeメソッドを使用して、必要な動作をするモックコンストラクターを作成しますMock。次に、メソッドを1つずつ追加する必要があります。調査しなかった理由により、のプロトタイプ全体をに設定すると、機能しませんでしUnderTestMock

require('chai').should();
const { fake} = require('sinon');

class UnderTest {
  constructor() {
    this.mocked = false;
  }

  isMocked() {
    return this.mocked;
  }
}

describe('UnderTest', () => {
  let underTest;
  let isMocked;
  before(() => {
    const Mock = fake(function () { this.mocked = true; });
    Mock.prototype.isMocked = UnderTest.prototype.isMocked;
    underTest = new Mock();
    isMocked = underTest.isMocked();
  });
  it('should be mocked', () => {
    isMocked.should.be.true;
  });
});

コンストラクターをダミーでスタブする

この投稿に誘導された場合は、コンストラクターをスタブして実行されないようにする必要があるためです。

Sinon'screateStubInstanceはスタブコンストラクターを作成します。また、すべてのメソッドをスタブします。したがって、テスト中のメソッドは前に復元する必要があります。

require('chai').should();
const { createStubInstance } = require('sinon');

class UnderTest {
  constructor() {
    throw new Error('must not be called');
  }

  testThis() {
    this.stubThis();
    return true;
  }

  stubThis() {
    throw new Error('must not be called');
  }
}

describe('UnderTest', () => {
  describe('.testThis()', () => {
    describe('when not stubbed', () => {
      let underTest;
      let result;
      before(() => {
        underTest = createStubInstance(UnderTest);
        underTest.testThis.restore();
        result = underTest.testThis();
      });
      it('should return true', () => {
        result.should.be.true;
      });
      it('should call stubThis()', () => {
        underTest.stubThis.calledOnce.should.be.true;
      });
    });
  });
});
于 2021-12-25T14:49:22.343 に答える
-19

いくつかの調整を行った後、 StubModuleを機能させることができました。特に、スタブモジュールで必要な場合に構成の一部としてasync:falseを渡すことができました。

それをまとめてくれたデイビス氏に称賛を送ります

于 2013-06-13T20:41:44.343 に答える