2016-05-23 1 views
0

失敗: 方法テスト中:xUnitの例外は、私は私のユニットテストが失敗した理由を知らない

public async Task<MyType> Get(string externalId) 
{ 
    if (externalId == null) 
     throw new ArgumentNullException(); 
    if (externalId == "" || externalId == " ") 
     throw new FormatException(); 
     // ... 
} 

ユニットテスト:

Action action = async() => await controller.Get(null); 

// Act & Assert 
action.ShouldThrow<ArgumentNullException>(); 

、エラーメッセージが言うので失敗があります:

ThrowされるArgumentNullExceptionが予想されましたが、実行はスローされませんでした。

このテストをデバッグする際に例外ラインがスローされたので、これは奇妙です!

私はxunitとfluentassertionsを使用しています。

+0

なぜ、あなたのユニットテストは、あなたのprodコードが含まれていますか?私は間違ったことをコピーして貼り付けたと思う。 [mcve]を入力してください。 –

+2

あなたはアクションを待っていないので、例外が発生しても例外は発生しません。アクションの代わりにFunc を使用し、それを待っていると例外が発生します。 –

+0

@MartinCostelloありがとう。 – Nerf

答えて

0

この行は問題です:

Action action = async() => await controller.Get(null); 

それはそれは非常に困難な例外を観察する(したがって、適切なテストを行う)することができasync voidメソッドを作成します。

Last time I checked、流暢アサーションは、「非同期」アサーションのアンチパターンのスタイルをサポートしています。シングルで使用した場合、それはbound to failですので

sut.Awaiting(…).ShouldThrow<T>(); 

は残念ながら、これは、ブロッキング同期オーバー非同期ハックを使用していますSynchronizationContext。ああ、と思ってwhich unit testing framework provides a single-threaded SynchronizationContext?あなたがxUnitを推測したら、あなたは賞金を得る。

したがって、「非同期」FAテストは、xUnitのデフォルトでは動作しません。あなたにはいくつかの選択肢があります。

スレッドプールスレッドでテスト全体を実行すると、xUnitのコンテキストを回避できます。これは効率的ではありませんが、ジョブは完了します。

await Task.Run(() => 
{ 
    controller.Awaiting(c => c.Get(null)).ShouldThrow<ArgumentNullException>(); 
}); 

あまり正確ではありません。

また、あなたはthe one I wroteのように、独自の非同期互換のアサーションを使用することができます。

await AsyncAssert.ThrowsAsync<ArgumentNullException>(() => controller.Get(null)); 
関連する問題