2013-09-19 3 views
14

Скажем, я хочу, чтобы проверить метод, возвращающий кучу элементов следующего типа с использованием fluent-assertions, чтобы убедиться, что все элементы имеют свой IsActive -flag набор для true:Как утверждать все элементы в коллекции, используя свободно утверждающие?

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

Для достижения этой цели я мог бы просто итерацию над сбор и утверждать каждый пункт отдельно в Еогеаспе петле:

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

Но есть более свободно способ утверждать каждый пункт во всей коллекции сразу?

ответ

23

Возможно, что-то вроде этого:

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!"); 
+1

Я думаю, что простой цикл foreach более чист и читабельнее, чем ваш первый подход. Но второй подход - хороший, который я искал! – Spontifixus

+1

@Spontifixus Я согласен, что первый был немного взломан, но это позволяет вам делать что-то, что не понравится второй - например. укажите другую причину для каждого элемента. Но да, цикл «foreach» будет работать так же хорошо для этого. –

+1

Ха-ха - третий тоже хороший, но мне все же нравится второй лучше;) – Spontifixus

3

Нечто подобное замене цикла Еогеасп с методом Еогеасп должен сделать трюк (по крайней мере, немного) ,

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

Я нахожу этот синтаксис немного более свободно, чем традиционный Еогеасп цикл :)

метод ForEach не определен, если ваш метод CreateABunchOfActiveItems возвращает IEnumerable. Но его можно легко реализовать в качестве метода расширения:

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; 
    } 
} 
+0

Это также действительный подход. И есть библиотеки, предоставляющие расширение 'ForEach'. Но я в основном смотрел, есть ли способ сделать это изначально с помощью библиотеки с плавным утверждением. – Spontifixus

+1

А также обратите внимание, что 'ToList()' уже перечисляет исходную коллекцию, которая затем снова подсчитывается 'foreach'-loop ... – Spontifixus

+0

Да, я знаю, что это может быть не лучший подход при работе с тяжелыми операциями (многие элементы, соединения db, filereading и т. д.), но мне это подходит для ежедневного тестирования. – Joel

Смежные вопросы