sinonスタブを簡単にクリーンアップ


134

モカのbeforeEachブロックで問題なく動作するすべてのsinonスパイのモックとスタブを簡単にリセットする方法はありますか?

サンドボックス化はオプションですが、これにサンドボックスを使用する方法はわかりません

beforeEach ->
  sinon.stub some, 'method'
  sinon.stub some, 'mother'

afterEach ->
  # I want to avoid these lines
  some.method.restore()
  some.other.restore()

it 'should call a some method and not other', ->
  some.method()
  assert.called some.method

回答:


304

Sinonは、いくつかの方法で使用できるサンドボックスを使用してこの機能を提供します。

// manually create and restore the sandbox
var sandbox;
beforeEach(function () {
    sandbox = sinon.sandbox.create();
});

afterEach(function () {
    sandbox.restore();
});

it('should restore all mocks stubs and spies between tests', function() {
    sandbox.stub(some, 'method'); // note the use of "sandbox"
}

または

// wrap your test function in sinon.test()
it("should automatically restore all mocks stubs and spies", sinon.test(function() {
    this.stub(some, 'method'); // note the use of "this"
}));

6
@CamJackson非同期テストがある場合は、最初のメソッドを使用する必要があります。そうしないと、テストの実行が完了する前にsinonがスタブをクリーンアップします。
keithjgrant 2014

3
> 5.0を使用している場合は、以下をお読みください。より簡単な方法があります:stackoverflow.com/a/55251560/4464702
RAnders00

53

以前の回答は使用を提案しています sandboxesこれを達成ためにするています、ドキュメントによると:

sinon@5.0.0以降、sinonオブジェクトはデフォルトのサンドボックスです。

つまり、スタブ/モック/スパイのクリーンアップは次のように簡単です。

var sinon = require('sinon');

it('should do my bidding', function() {
    sinon.stub(some, 'method');
}

afterEach(function () {
    sinon.restore();
});

10
これは、2018
Nick Cox

1
さらにニーター:afterEach(sinon.restore)
ベンジャム

明示的なサンドボックスは不要な複雑さを生み出すので、これはより良いと思います。同じオブジェクトのモックが異なるいくつかのサンドボックスが本当に必要ですか?おそらく違います。
ガーマン

13

@keithjgrant回答の更新。

バージョンv2.0.0以降、sinon.testメソッドは別のsinon-testモジュールに移動しまし。古いテストに合格するには、各テストでこの追加の依存関係を構成する必要があります。

var sinonTest = require('sinon-test');
sinon.test = sinonTest.configureTest(sinon);

または、サンドボックスsinon-testを使用せずに使用します

var sandbox = sinon.sandbox.create();

afterEach(function () {
    sandbox.restore();
});

it('should restore all mocks stubs and spies between tests', function() {
    sandbox.stub(some, 'method'); // note the use of "sandbox"
} 

1
それとも、ただ、実際にsinonテストパッケージを使用して:-D以前のようにあなたのコードを続けることができます
oligofren

10

これに示されているように、sinon.collectionを使用できます。ブログ投稿(2010年5月付け)にあるように、sinonライブラリの作成者ます。

sinon.collection apiが変更され、使用方法は次のとおりです。

beforeEach(function () {
  fakes = sinon.collection;
});

afterEach(function () {
  fakes.restore();
});

it('should restore all mocks stubs and spies between tests', function() {
  stub = fakes.stub(window, 'someFunction');
}

6

restore()スタブ機能の動作を復元するだけですが、スタブの状態をリセットしません。テストをラップしsinon.testて使用するthis.stubreset()、スタブを個別に呼び出す必要があります


6

sinonを使用する設定が必要な場合は、すべてのテストで常にそれ自体をリセットします。

helper.js:

import sinon from 'sinon'

var sandbox;

beforeEach(function() {
    this.sinon = sandbox = sinon.sandbox.create();
});

afterEach(function() {
    sandbox.restore();
});

次に、テストで:

it("some test", function() {
    this.sinon.stub(obj, 'hi').returns(null)
})

3

モカの代わりにqunitを使用する場合、これらをモジュールにラップする必要があることに注意してください。

module("module name"
{
    //For QUnit2 use
    beforeEach: function() {
    //For QUnit1 use
    setup: function () {
      fakes = sinon.collection;
    },

    //For QUnit2 use
    afterEach: function() {
    //For QUnit1 use
    teardown: function () {
      fakes.restore();
    }
});

test("should restore all mocks stubs and spies between tests", function() {
      stub = fakes.stub(window, 'someFunction');
    }
);

3
qunit 2はbeforeEachおよびに切り替えていafterEachます。setupおよびteardown方法が廃止されます。
Kevin Bullaughey、2015年

0

すべてのスパイ、スタブ、モック、フェイクのブラックボックスコンテナーとして機能するサンドボックスを作成します。

最初の記述ブロックにサンドボックスを作成するだけで、すべてのテストケースでアクセスできます。すべてのテストケースが完了したら、元のメソッドをリリースし、メソッドを使用してスタブをクリーンアップする必要があります sandbox.restore()し、afterEachフックのて、実行時に保留されたリソースを解放する必要がありますafterEachテストケースが成功または失敗するようにします。

次に例を示します。

 describe('MyController', () => {
    //Creates a new sandbox object
    const sandbox = sinon.createSandbox();
    let myControllerInstance: MyController;

    let loginStub: sinon.SinonStub;
    beforeEach(async () => {
        let config = {key: 'value'};
        myControllerInstance = new MyController(config);
        loginStub = sandbox.stub(ThirdPartyModule, 'login').resolves({success: true});
    });
    describe('MyControllerMethod1', () => {
        it('should run successfully', async () => {
            loginStub.withArgs({username: 'Test', password: 'Test'}).resolves();
            let ret = await myControllerInstance.run();
            expect(ret.status).to.eq('200');
            expect(loginStub.called).to.be.true;
        });
    });
    afterEach(async () => {
        //clean and release the original methods afterEach test case at runtime
        sandbox.restore(); 
    });
});
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.