2016-06-18 10 views
3

私の依存関係の1つである.then.catchブロックで実行したいテストがいくつかあります。sinonでスタブしたときのava非同期テストの問題

import test from 'ava'; 
import sinon from 'sinon'; 

// Fake dependency code - this would be imported 
const myDependency = { 
    someMethod:() => {} 
}; 

// Fake production code - this would be imported 
function someCode() { 
    return myDependency.someMethod() 
     .then((response) => { 
      return response; 
     }) 
     .catch((error) => { 
      throw error; 
     }); 
} 

// Test code 

let sandbox; 

test.beforeEach(() => { 
    sandbox = sinon.sandbox.create(); 
}); 

test.afterEach.always(() => { 
    sandbox.restore(); 
}); 

test('First async test', async (t) => { 
    const fakeResponse = {}; 

    sandbox.stub(myDependency, 'someMethod') 
     .returns(Promise.resolve(fakeResponse)); 

    const response = await someCode(); 

    t.is(response, fakeResponse); 
}); 

test('Second async test', async (t) => { 
    const fakeError = 'my fake error'; 

    sandbox.stub(myDependency, 'someMethod') 
     .returns(Promise.reject(fakeError)); 

    const returnedError = await t.throws(someCode()); 

    t.is(returnedError, fakeError); 
}); 

いずれかのテストだけを実行すると、テストに合格します。あなたが一緒にこれらを実行した場合でも、テストAのためのセットアップが実行され、その後、それは、テストBの実行のためのセットアップを完了し、このエラーを取得する前に:

Second async test 
    failed with "Attempted to wrap someMethod which is already wrapped" 

は、たぶん私は理解していないよをどのようにI私のテストを設定する必要があります。テストBが実行を開始する前にテストAを完了させる方法はありますか?

答えて

8

AVAテストは同時に実行されるため、Sinonスタブが壊れます。

代わりに、あなたのテストを宣言実行するserially、それが動作するはずです:働い

test.serial('First async test', ...); 
test.serial('Second async test', ...); 
+0

。ありがとう! –

+8

これについてより多くの背景を提供するために、デフォルトでは、テストは同時に実行されます。これは、すべてのテストの 'beforeEach'フックが同時に実行されることを意味します。起こっているのは、 'beforeEach'フックを呼び出すたびに' sandbox'変数が置き換えられるため、両方のテストが実際に同じサンドボックスを使用するということです。 'beforeEach'の' t.context'に割り当てることで修正できます。これはテストでも利用可能です。 ただし、両方のテストで同じ依存関係が変更されているため、2番目のテストでもメソッドをスタブすることはできません。したがって 'test.serial'が必要です。 –

+0

洞察のおかげで@MarkWubben :) – robertklep

関連する問題