
[FluentAssertions] よく使う!検証メソッド一覧
1. はじめに
今回はC#のユニットテストフレームワークの一つである、 FluentAssertions でよく使う検証メソッドについて、使用例とどのようなときに使っているのかをまとめていきたいと思います。
2. 環境
- FluentAssertions 6.10.0
- .NET Framework 4.8
3. FluentAssertions ってなに?
(おそらく)一番メジャーなC#のユニットテストフレームワークです。
Assert.AreEqual() のように書く MSTest よりも人間に理解しやすい拡張メソッドでの提供になっていたり、 MSTest よりもできることが多いです。
ただ、 公式ドキュメント を見てもわかる通り、できることが多すぎて逆にどのような場合にどのメソッドを使うのがいいの?ってなることがあるんですよね。
そのような方々のためによく使う、使えるメソッドをいくつかあげてみようと思います。
4. 基本的な検証
値の比較
[<span class="hljs-meta">TestMethod</span>]
<span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> TestMethod1
{
<span class="hljs-keyword">var</span> actual = <span class="hljs-number">3</span> + <span class="hljs-number">2</span>;
<span class="hljs-keyword">var</span> expected = <span class="hljs-number">5</span>;
actual.Should().Be(expected); <span class="hljs-comment">// Successfully</span>
}
知っている方もいらっしゃると思いますがよく使用されるものです。
FluentAssertions メソッドは、「実際の値.Should().Be(期待値)」という形が基本です。
英文法的に理解しやすくていいですよね。
Null比較
[<span class="hljs-meta">TestMethod</span>]
<span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> TestMethod2
{
<span class="hljs-built_in">object</span>? actual = <span class="hljs-literal">null</span>;
actual.Should().BeNull(); <span class="hljs-comment">// Successfully</span>
}
実際の値がNullかどうかを検証してくれます。そこそこ使います。
論理値の比較
[<span class="hljs-meta">TestMethod</span>]
<span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> TestMethod3
{
<span class="hljs-keyword">var</span> actual = <span class="hljs-literal">true</span>;
actual.Should().BeTrue(); <span class="hljs-comment">// Successfully</span>
actual.Should().BeFalse(); <span class="hljs-comment">// Failure</span>
}
実際の値がTrueかどうか、Falseかどうかを検証してくれます。 Should().Be()でやることが多く、実はあまり使わないかも。
5. コレクションの検証
[<span class="hljs-meta">TestMethod</span>]
<span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> TestMethod4
{
<span class="hljs-keyword">var</span> actual = <span class="hljs-keyword">new</span>[] { <span class="hljs-string">"Apple"</span>, <span class="hljs-string">"Grape"</span>, <span class="hljs-string">"Banana"</span> };
<span class="hljs-keyword">var</span> expected = <span class="hljs-keyword">new</span>[] { <span class="hljs-string">"Apple"</span>, <span class="hljs-string">"Grape"</span>, <span class="hljs-string">"Banana"</span> };
actual.Should().ContainInOrder(expected); <span class="hljs-comment">// Successfully</span>
}
コレクションの検証には Should().ContainInOrder() をよく使っています。 これは順序まで見てくれるためです。
6. オブジェクトの検証
オブジェクトの比較
<span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Sample</span>
{
<span class="hljs-keyword">public</span> <span class="hljs-built_in">string</span> Hoge { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }
}
[<span class="hljs-meta">TestMethod</span>]
<span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> TestMethod5
{
<span class="hljs-keyword">var</span> actual = <span class="hljs-keyword">new</span> Sample() { Hoge = <span class="hljs-string">"fugafuga"</span> };
<span class="hljs-keyword">var</span> expected = <span class="hljs-keyword">new</span> Sample() { Hoge = <span class="hljs-string">"fugafuga"</span> };
actual.Should().BeEquivalentTo(expected); <span class="hljs-comment">// Successfully</span>
}
オブジェクト(クラスなど)の検証をしてくれます。Should().Be() の次ぐらいにめちゃくちゃ使ってます。
Should().Be() でのオブジェクトの検証は異なるインスタンスだと失敗になります( == での等価比較と同様)。
そのためこちらを利用することになります。
複雑な構造をしているクラスを返すメソッドを検証したいときに利用することが多いですね。
高度なオブジェクトの比較
オブジェクトの比較では、第二引数のオプションを利用することでより細かい条件を付与することができます。サンプルコードはオプションメソッド WithStrictOrdering() を利用して、オブジェクトのコレクションを順序まで検証しています。
他にもたくさんのオプションメソッドが用意されています。
公式ドキュメントのオブジェクト比較のページ を見て、いろいろ試してみるといいかもしれません。
7. 例外の検証
[<span class="hljs-meta">TestMethod</span>]
<span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> TestMethod7
{
Action action = () =>
{
<span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> ArgumentException(<span class="hljs-string">"この値は不正です。"</span>);
}
action.Should().Throw<ArgumentException>(); <span class="hljs-comment">// 例外の型だけ検証</span>
action.Should().Throw<ArgumentException>().WithMessage(<span class="hljs-string">"この値は不正です。"</span>); <span class="hljs-comment">// メッセージまで検証</span>
}
WithInnerException() を利用することで、内部例外の検証も可能です。
非同期処理、並列処理などで AggregateException が発生する場面で利用することが多いです。
[<span class="hljs-meta">TestMethod</span>]
<span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> TestMethod8
{
Action action = () =>
{
<span class="hljs-comment">// エラー処理</span>
}
action.Should().Throw<AggregateException>().WithInnerException<TimeoutException>();
}
WithInnerException() を利用することで、内部例外の検証も可能です。非同期処理、並列処理などで AggregateException が発生する場面で利用することが多いです。
8. 最後に
今回は私が個人的によく使う、使えると思った FluentAssertions 検証メソッドを紹介しました。
公式ドキュメントにもある通り、FluentAssertions はここで紹介したメソッド以外にも多くの便利な検証メソッドが用意されています。
こういうのは実際に使って試してみるのが一番です。
余談ですが、FluentAssertions を使ってて感じたのが、メジャーなフレームワークの割には意外と日本語の記事が出てこないんですよね。
なのでこの記事が少しでも実装の助けになればと思ってます!