Почему NUnit не имеет ограничения IsElementOf / IsOneOf? - PullRequest
5 голосов
/ 18 июня 2011

Я не работаю с NUnit напрямую, но собираюсь позаимствовать некоторые из его идей в другом контексте.

Одна особенно изящная идея - это механизм ограничений, который позволяет вам написать модульный тест формы:

Assert.That(aValue, Is.GreaterThan(2.0) & Is.LessThan(5.0));

Вы также можете проверить, что значение находится в некотором диапазоне:

Assert.That(aValue, Is.InRange(2.0, 5.0));

Однако, похоже, нет способа проверить, что aValue является одним изколлекция допустимых значений:

Assert.That(aValue, Is.OneOf(aCollection));

Разве это не так часто встречается в модульном тесте?Это указывает на какую-то проблему с моими юнит-тестами?Все ли просто вставляют aValue в какую-то пустую коллекцию из одного элемента, а затем используют Is.SubsetOf?

Ответы [ 2 ]

3 голосов
/ 18 июня 2011

API утверждений - это все о удобочитаемости, и нет никакой выгоды в том, что Is.OneOf (collection) удобочитаемости для этого:

Assert.That(collection.Contains(value));

Он читабелен и понятен, поэтому дублирует каждый случай в API Assersion.не правильно, если это ничего не приносит.Насколько вы можете видеть, не существует простого способа написания альтернативы Is.InRange и Is.GreaterThan + Is.LessThan более редабируем, чем

Assert.That(value > 2.0 && value < 5.0);
//compared to
Assert.That(value, Is.GraterThan(2.0).And.Is.LessThan(5.0));
1 голос
/ 19 июня 2011

@ Lambdageek;

Assert.That(aCollection, Has.Member(aValue) 
Assert.That(aCollection, Has.No.Member(aValue) 

был вокруг некоторое время. Существует также множество других полезных ограничений коллекции, прилично документированных здесь .

В дополнение к удобочитаемости вы также получаете гораздо более полезный уровень обратной связи, когда что-то не получается. Стоит крошечных дополнительных усилий, ИМО.

EDIT

    [Test]
    public void Test() {
        var c = new[] {"one", "two"};
        Assert.That(c, Has.Member("three"));
    }

Test failed:
  Expected: collection containing "three"
  But was:  < "one", "two" >
    Tests.cs(73,0): at ...Test()

Приветствия
Berryl

Бедный человек

public static class TestExtensions
{
    public static bool IsOneOf<T>(this T candidate, IEnumerable<T> expected) {
        if (expected.Contains(candidate)) return true;

        var msg = string.Format("Expected one of: '{0}'. Actual: {1}", ", "._insertBetween(expected.Select(x => Convert.ToString(x))), candidate);
        Assert.Fail(msg);
        return false;
    }

    private static string _insertBetween(this string delimiter, IEnumerable<string> items)
    {
        var builder = new StringBuilder();
        foreach (var item in items)
        {
            if (builder.Length != 0)
            {
                builder.Append(delimiter);
            }
            builder.Append(item);
        }
        return builder.ToString();
    }

    internal static IEnumerable<string> GenerateSplits(this string str, params char[] separators)
    {
        foreach (var split in str.Split(separators))
            yield return split;
    }

}

Неудачный тест

    [Test]
    public void IsOneOf_IfCandidateNotInRange_Error()
    {
        IEnumerable<string> expected = new[] { "red", "green", "blue" };
        const string candidate = "yellow";
        Assert.That(candidate.IsOneOf(expected));
    }

IsOneOf_IfCandidateNotInRange_Error' failed:
Expected one of: 'red, green, blue'. Actual: yellow
...