NUnit(とか) に簡単なアサーションを提供してくれる Chaining Assertion

先日の Should の記事の

ブックマークコメントで id:neuecc さんにコメントいただき、「Chaining Assertion」を紹介いただきました。neuecc さんはライブラリの作者さんですね。ありがとうございます。

Should はどうだ?

個人的には、Should の書き方にはそれほど違和感ありません。NSpec のように should_be のようだと ruby っぽいし、見た目にも読みやすいから好きなのですが、社内の人の中には C# っぽくないから嫌だとの意見もあるためこの辺も人によりそうです。

ただ、ShouldFluent の書き方は実際書いてみてかなり面倒くさいなーというのは感じました。特に私がドットをよく押し間違えるので、ちょっとしたストレスに。。(完全私のせいですが。)
ただ、それを差し引いても、ちょっとメリットが見えなかったので結局 Should の方で書いていました。

以下の記事でも言及されていますね。
テストを簡単にするほんの少しの拡張メソッド - neue cc

Chaining Assertion

使い方

例によって、CodePlex の方のサンプルで十分なので先日の Should, ShouldFluent と比較したものだけ以下に記載します。
NuGet で取得した時に dll ではなくソースが追加されるだけってのはいいですね。すぐ中を見ることができる。

[TestFixture]
public class dSample {

    [TestCase]
    public void TestShouldAny() {
        var exist = "result";
        var empty = "";
        var stringEmpty = string.Empty;
        string nullValue = null;

        exist.ShouldNotBeEmpty();
        exist.ShouldNotBeNull();
        exist.ShouldBeSameAs(exist);
        exist.ShouldBeType<string>();
        exist.ShouldContain("su");
        exist.ShouldEqual("result");

        empty.ShouldBeEmpty();
        stringEmpty.ShouldBeEmpty();
        nullValue.ShouldBeNull();
    }

    [TestCase]
    public void TestShouldFluent() {
        var exist = "result";
        var empty = "";
        var stringEmpty = string.Empty;
        string nullValue = null;

        exist.Should().Not.Be.Empty();
        exist.Should().Not.Be.Null();
        exist.Should().Equals(exist);
        exist.ShouldBeType<string>();
        exist.Should().Contain("su");
        exist.Should().Equal("result");

        empty.Should().Be.Empty();
        stringEmpty.ShouldBeEmpty();
        stringEmpty.Should().Be.Empty();
        nullValue.Should().Be.Null();
    }

    [TestCase]
    public void TestChainingAssertion() {
        var exist = "result";
        var empty = "";
        var stringEmpty = string.Empty;
        string nullValue = null;

        exist.IsNotNull();
        exist.IsSameReferenceAs(exist);
        exist.IsInstanceOf<string>();
        exist.Is(s => s.Contains("su"));
        exist.Is("result");

        empty.Is(string.Empty);
        stringEmpty.Is(string.Empty);
        nullValue.IsNull();
    }
}

実際ソースを見てみてもわかるのですが、非常にシンプルでキレイです。確かに rspec を見て、最初に思ったのは、「すげー簡単にテストかけるんだなー」って部分が一番大きくて、should って記法で書けることに感動したわけじゃなかったよなと改めて思い出しました。

次は

DynamicAccessor 使ってみたいですね。Private なものをテストしなきゃいけなくなる事自体が決して良い状況じゃないですが、レガシーコードをテストするには欠かせない部分の気がするのですごく活用したいです。

という訳で、「Should はもういいかな」。