独自のアサーションを作る
(サンプルコード:「その12_独自のアサーションを作る」クラス)
NUnitは、どうやってテストの成功/失敗を判断しているのでしょう? テストメソッドから例外が投げられると、失敗と判定しているのです。ということは、何らかの判定をして例外を投げるメソッドを用意すれば、独自のアサーションとして利用できることになります。投げる例外をNUnitのAssertionException
にしておくと、失敗時のエラーメッセージも分かりやすくなります。
private static void AssertEven(int n) { if (n % 2 != 0) { var msg = string.Format( @" 期待値: 偶数 実際は: {0}", n); throw new AssertionException(msg); } } [Test] public void Test01_独自に定義したAssertメソッドを使う_RED() { AssertEven(3); }
また、Assert.That()
で使う制約も、NUnitのConstraint
クラスを継承して独自のものを作ることができます(Custom Constraints)。次の例では、偶数かどうかを判定するEvenConstraint
クラスを作っています。
[TestFixture] public class その12_独自のアサーションを作る { [Test] public void Test02_独自に作成したEvenConstraintを使う() { Assert.That(8, MyConstraint.IsEven()); Assert.That(new int[] { 2, 4, 6 }, Is.All.Even()); } } public class EvenConstraint : Constraint { // 検証メソッド public override bool Matches(object actual) { base.actual = actual; var en = actual as IEnumerable; if (en != null) return en.Cast<object>().All(o => IsObjectEven(o)); return IsObjectEven(actual); } private static bool IsObjectEven(object o) { var num = o as int?; return (num != null) && (num.Value % 2 == 0); } // 出力 public override void WriteDescriptionTo(MessageWriter writer) { writer.Write("偶数"); } } public static class MyConstraint { public static Constraint IsEven() { return new EvenConstraint(); } } public static class ConstraintExtension { public static Constraint Even(this object n) { return new EvenConstraint(); } }