Проверка полного сопоставления [неупорядоченной] коллекции/набора элементов в модульном тесте

Я использую xUnit.net, AutoFixture и SemanticComparison и хочу проверить результаты сопоставления.

На уровне отдельных элементов я хорошо охвачен.

Дано

  • Элементы имеют общий идентификационный ключ
  • Я хочу сделать сравнение элементов значения с обеих сторон
  • Я не забочусь о заказе (и не хочу, чтобы мое утверждение сломалось при повторном заказе)

Как убедиться, что каждый входной элемент соответствует одному и только одному выходному элементу в ВЫСОКИЙ, но СУХОЙ способ с использованием как можно большего количества компонентов OOTB ?

Светильники:

class Input
{ 
   public string Name, Description;
}

class Output
{ 
   public string Name, Description, IgnoreThisField;
}

Тест скелета:

[Theory,AutoData]
void MappingWorks( Mapper sut, Input[] inputs)
{
    var outputs = sut.Map( inputs);

    // TODO assert that every input is mapped
    // TODO assert that we have have no extra outputs
}

person Ruben Bartelink    schedule 23.05.2013    source источник


Ответы (2)


Учитывая [очень аккуратно] операцию FullOuterJoin и xUnit.net V2, вы можете выразить это как:

static void VerifyFeaturesetFullyMapped(
    IEnumerable<Output> outputs,
    IEnumerable<Input> inputs )
{
    Assert.All(
        inputs.FullOuterJoin( outputs,
            f => f.Item1, r => r.Name,
            ( x, y, key ) => new { 
                InDescription = x.Item2, 
                OutDescription = y.Description } ),
        inout =>
            Assert.Equal( inout.InDescription, inout.OutDescription ) );
}
person Ruben Bartelink    schedule 23.05.2013

Имея несколько AssertResemblance.Like помощников для коллекций[1], вы

  1. Поместите их в том же порядке (что наиболее четко выполняется в теле теста, поскольку входные и выходные коллекции будут разных типов, и если SemanticComparison не вырастет функция, я не думаю, что ее можно с пользой обобщить)
  2. Пусть Likeness из Ploeh.SemanticComparison сопоставят Name
  3. Пусть Assert.Collection xUnit.net V2 выполнит корреляцию (она еще не дает большого сообщения)

Окончательный результат:

var results = from result in outputs orderby result.Name select result;

var expectations = from input in inputs orderby input.Name select input;
AssertResemblance.Like( expectations, results, 
   configure=>configure
      .Without(x=>x.IgnoreThisField) );

[1]

static class AssertResemblance
{
    public static void Like<T, T2>( IEnumerable<T> expected, IEnumerable<T2> actual )
    {
        Like<T, T2>( expected, actual, x=>x );
    }

    public static void Like<T, T2>( IEnumerable<T> expected, IEnumerable<T2> actual, Func<Likeness<T, T2>, Likeness<T, T2>> configureLikeness )
    {
        Assert2.Collection( actual, SelectShouldEqualAsAction( expected.Select( x => configureLikeness( x.AsSource().OfLikeness<T2>() ) ) ) );
    }

    public static void Like<T>( IEnumerable<T> expected, IEnumerable<T> actual, Func<IEnumerable<T>, IEnumerable<T>> unify )
    {
        Like<T>( expected, actual, unify, x=>x );
    }

    public static void Like<T>( IEnumerable<T> expected, IEnumerable<T> actual, Func<IEnumerable<T>,IEnumerable<T>> unify, Func<Likeness<T, T>, Likeness<T, T>> configureLikeness )
    {
        Assert2.Collection( unify( actual ), SelectShouldEqualAsAction( unify(expected).Select( x => configureLikeness( x.AsSource().OfLikeness<T>() ) ) ) );
    }

    static Action<TDestination>[] SelectShouldEqualAsAction<TSource, TDestination>( IEnumerable<Likeness<TSource, TDestination>> that )
    {
        return (from it in that select (Action<TDestination>)it.ShouldEqual).ToArray();
    }
}
person Ruben Bartelink    schedule 24.05.2013