Verifying complete Mapping of an [unordered] Collection/Set of Items in a Unit Test

只愿长相守 提交于 2019-12-18 09:24:08

问题


I'm using xUnit.net, AutoFixture and SemanticComparison and want to verify the results of a mapping.

On the individual item level, I'm well covered.

Given

  • The items share an identifying key
  • I want to do a comparison on the value elements on both side
  • I don't care about ordering (and don't want my Assertion to break under re-ordering)

How do I verify that each and every input item maps to one and only one output item in a DAMP yet DRY manner using as much OOTB componentry as possible ?

Fixtures:

class Input
{ 
   public string Name, Description;
}

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

Skeleton Test:

[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
}

回答1:


Given some AssertResemblance.Like Collection helpers[1], you

  1. Put them in the same order (which is most cleanly done in the test body as the input and output collections will be of different types and unless SemanticComparison grows a feature I don't think it can be usefully generalised)
  2. Let Ploeh.SemanticComparison's Likeness do the matching on Name
  3. Let xUnit.net V2's Assert.Collection do the correlation (it doesn't yet give a greate message)

Final result is:

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();
    }
}



回答2:


Given a [very neat] FullOuterJoin operation and xUnit.net V2, you can express it as:

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 ) );
}


来源:https://stackoverflow.com/questions/16716161/verifying-complete-mapping-of-an-unordered-collection-set-of-items-in-a-unit-t

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!