拡張メソッドでNUnitを快適にする
public static class Extention { public static void should_be<T>(this T th,T expected) {Assert.AreEqual(th,expected);} }
で、
//before Assert.AreEqual(obj.DoSomething(),"result"); Assert.That(obj.DoSomething(),Is.EqualTo("result")); //2.4の新記法らしい。長くなってる……>< //after obj.DoSomething().should_be("result");
とてもかわいいですね。
そしてこれは序の口。拡張メソッドを使えば例外テストも自然に記述できる。
今までは
//before [ExpectedException(typeof(ArgumentException))] public static ExceptionTest() { obj.DoIllegal(); } //あるいは try { obj.DoIllegal(); Assert.Fail("ArgumentException expected"); } catch(ArgumentException) { }
これがこう書ける
//after This.Operation( delegate{ obj.DoIllegal(); } ).throws<ArgumentException>();
すごく自然!
ちょうかわいい!
実装はこんなかんじ。
public static class This { public static OperationHolder Operation(OperationDelegate op) { return new OperationHolder(op); } public delegate void OperationDelegate(); public class OperationHolder { public OperationHolder(OperationDelegate o) { op = o; } public OperationDelegate op; public void throws<T>() where T:Exception { try { op(); Assert.Fail("Exception "+typeof(T).Name+" expected but nothing"); } catch (T) { //success } catch (Exception e) { if (e.GetType().IsKindOf(typeof(AssertionException))) throw; //NUnitが使ってる例外 Assert.Fail("Exception "+typeof(T).Name+" expected but "+e.GetType().Name); } } } } public static class TypeExtention { public static bool IsKindOf(this Type t1,Type t2) { return t1==t2 || t1.IsSubclassOf(t2); } }
ここまで書いてから上の例は拡張メソッドと特に関係なくC#2.0でも可能なことに気づいたが、なんにしろC#はかわいいので問題はない。