dimanche 15 décembre 2019

Reusing build-in object graph comparison in custom assertions in FluentAssertions

How can I reuse the FluentAssertions' build-in object graph comparison in my custom assertions class, so that I can use the options parameter to scope the comparison.

Here is an example. There is a base entity called record that can represent several other entities. Next is an Entity it represents.

public class Record
{
    public long No;
    public string Version;
    public string Type;
    public string[] Fields = new string[10];
}

public class Projection
{
    private readonly Record _Record;
    public Projection(Record record)
    {
        _Record = record;
    }
    public String Field1 => _Record.Fields[2];
    public String Field2 => _Record.Fields[5];
    public String Field3 => _Record.Fields[8];
    public static readonly EmptyFields = new array[] { 0, 1, 3, 4, 6, 7, 9 };
}

I have created a custom assertions class for Projection class

public class ProjectionAssertions : ReferenceTypeAssertions<Projection, ProjectionAssertions>
{
    protected override string Identifier => "Projection";

    public ProjectionAssertions(Projection instance)
    {
        Subject = instance;
    }

    public AndConstraint<ProjectionAssertions> BeProjection(
        string because = "",
        params object[] becauseArgs)
    {
        Subject.Type.Should().Be("PRJ", because, becauseArgs);

        return new AndConstraint<ProjectionAssertions>(this);
    }

    public AndConstraint<ProjectionAssertions> BeEquivalentTo(
        ProjectionFields expected,
        string because = "",
        params object[] becauseArgs)
    {
        Execute.Assertion.
            BecauseOf(because, becauseArgs).
            ForCondition(expected != null).
            FailWith("'expected' should not be null.").
            Then.
            Given(() => Subject).
                ForCondition(s => s.Field1 == expected.Field1).
                FailWith("message1").
            Then.
                ForCondition(s => s.Field2 == expected.Field2).
                FailWith("message2").
            Then.
                ForCondition(s => s.Field3 == expected.Field3).
                FailWith("message3");

        return new AndConstraint<ProjectionAssertions>(this);
    }
}

But I would like to do something like the following in my custom BeEquivalentTo method to :

var fieldsToCheck = List<string>() { "Version", "Type" };
record.Should().
    BeEquivalentTo(
        expectedRecord,
        options => options.Including(ctx => fieldsToCheck.Contains(ctx.SelectedMemberPath)))

How can I achieve this?

Aucun commentaire:

Enregistrer un commentaire