web-dev-qa-db-ja.com

fluent-assertionsを使用してコレクション内のすべてのアイテムをアサートする方法は?

fluent-assertions を使用して、次のタイプのアイテムの束を返すメソッドをテストし、すべてのアイテムのIsActive-フラグがtrueに設定されていることを確認するとします。 :

public class Item
{
    public bool IsActive { get; set; }
}

これを実現するには、コレクションを繰り返し処理し、foreachループですべてのアイテムを個別にアサートします。

var items = CreateABunchOfActiveItems();
foreach (var item in items)
{
    item.IsActive.Should().BeTrue("because I said so!");
}

しかし、コレクション全体のすべてのアイテムを一度にアサートするためのより流暢な方法はありますか?

19
Spontifixus

おそらくこのようなもの:

_var items = CreateABunchOfActiveItems();
items.Select(x => x.IsActive.Should().BeTrue("because I said so!"))
     .All(x => true); 
_

最後の行(.All(x => true))は、前のSelectを各アイテムに対して強制的に実行することに注意してください。

またはさらに良い:

_var items = CreateABunchOfActiveItems();
items.Should().OnlyContain(x => x.IsActive, "because I said so!");
_

またはあなたが好きかもしれない別の解決策:

_var items = CreateABunchOfActiveItems();
items.All(x => x.IsActive).Should().BeTrue("because I said so!");
_
33
p.s.w.g

Foreachループをforeachメソッドに置き換えるようなもので、うまくいくはずです(少なくとも少しは)。

var items = CreateABunchOfActiveItems();
items.ForEach(item => item.IsActive.Should().BeTrue("because I said so, too!"));

この構文は、従来のforeachループよりも少し流暢だと思います:)

メソッドCreateABunchOfActiveItemsがIEnumerableを返す場合、ForEachメソッドは定義されていません。ただし、拡張メソッドとして簡単に実装できます。

public static IEnumerable<T> ForEach<T>(this IEnumerable<T> enumeration, 
    Action<T> action)
{
    // I use ToList() to force a copy, otherwise your action 
    // coud affect your original collection of items!. If you are confortable 
    // with that, you can ommit it
    foreach (T item in enumeration.ToList())
    {
        action(item);
        yield return item;
    }
}
4
Joel