1

I'm using Ploeh.SemanticComparison's Likeness as a way to effectively express intended outputs of a mapping process (as described in Mark Seemann's excellent Advanced Unit Testing course on PluralSight).

I'm testing some data has mapped correctly, which looks like this:

[Theory, AutoData]
static void ShouldYieldIdentifierUpdatedEvent( Vendor sut, string name, string version, Guid id )
{
    var result = sut.SyncProduct( name, version, id );

    var expected = new { ProductId = id, Name = name, Version = version };
    expected.AsSource().OfLikeness<NewMappingsEvent>()
        .Without( y => y.ProgrammaticIdentifier)
        .ShouldEqual(result);
}

However, I'm not happy:-

  1. I want to apply a name to the Resemblance (i.e. name my .Without( y => y.ProgrammaticIdentifier) customization)
  2. I've lost the symmetry with Assert.Equal( expected,actual, comparer) (but I definitely need the error message from ShouldEqual)

Is there a cleaner way to express this within the expressed constraints?

Nikos Baxevanis
  • 10,868
  • 2
  • 46
  • 80
Ruben Bartelink
  • 59,778
  • 26
  • 187
  • 249
  • 2
    Hi Ruben, with the current API, that's the only way to do it. In the (near) future though it will be possible to use an auto-mapping library (e.g. AutoMapper) so you could use your auto-mapping library of choice to create customizations, profiles, configurations, and so on. – Nikos Baxevanis May 23 '13 at 13:35
  • @NikosBaxevanis I've been scanning that thread and it's clear good things are afoot in there, but if you'll pardon the pun, it's largely Greek to me in terms of really grokking it :P And I like the syntax in `Ploeh.SemanticComparison` (i.e., I have yet to run into a case I can't contort to fit my Golden Hammer as yet :D) – Ruben Bartelink May 23 '13 at 13:40

1 Answers1

1

If you had an Assertion helper class called AssertResemblance (like [4]), and a static helper like [1] in scope you could say it like:

var expected = new { ProductId = id, Name = name, Version = version };
AssertResemblance.Like( expected, result, WithoutProgrammaticIdentifier );

Or if you had an extension method like [2], you could do it like:

AssertResemblance.Like( expected,result,x=>x.WithoutProgrammaticIdentifier());

Or you could have the best of both worlds (no noise as in the first snippet) yet naming the Resemblance (by having the actual impl in an extension method) by implementing a local static helper in terms of the extension method ([2]) as in [3].


[1]

public static Likeness<T, NewMappingsEvent> WithoutProgrammaticIdentifier<T>( Likeness<T, NewMappingsEvent> that )
{
    return that.Without( x => x.ProgrammaticIdentifier );
}

[2]

static class NewMappingsEventResemblances
{
    public static Likeness<T, NewMappingsEvent> WithoutProgrammaticIdentifier<T>( this Likeness<T, NewMappingsEvent> that )
    {
        return that.Without( x => x.ProgrammaticIdentifier );
    }
}

[3]

static Likeness<T, NewMappingsEvent> WithoutProgrammaticIdentifier<T>( Likeness<T, NewMappingsEvent> that )
{
    return that.WithoutProgrammaticIdentifier();
}

[4]

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

    public static void Like<T, T2>( T expected, T2 actual, Func<Likeness<T, T2>, Likeness<T, T2>> configureLikeness )
    {
        var likeness = expected.AsSource().OfLikeness<T2>();
        configureLikeness( likeness ).ShouldEqual( actual );
    }
}
Ruben Bartelink
  • 59,778
  • 26
  • 187
  • 249