0

Often in my team people forget to map certain fields from an input object to an output object. I wanted to write a library for unit testing, that checks if all properties on an output object have been filled with a value different than the default value, if not, an exception should be thrown. Ofcourse certain properties will need to be able to be excluded.

I noticed that Fluent Assertions can already do this with the .Should().BeEquivalentTo() Graph comparison.

However, I when a property is not present on the input object, I run into some trouble. Given the following objects:

public class Input
{
    public int Age{ get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
}
public class Output
{
    public int Age { get; set; }
    public string FullName{ get; set; }

    public static Output CreateFrom(Input i)
    {
        return new Output
        {
            Age = i.Age,
            FullName= $"{i.FirstName} {i.LastName}"
        };
    }
}

When I do the following assertion:

var input = new Input
{
    Age = 33,
    FirstName = "Foo",
    LastName = "Bar"
};

var output = Output.CreateFrom(input);

var fullName = $"{input.FirstName} {input.LastName}";

input.Should().BeEquivalentTo(output, 
    o => o.Using<string>(i => i.Subject.Should().Be(fullName)).When(
    info => info.Path.Contains(nameof(output.FullName)))
);

I get an exception that FullName is not a property on the Input object, which is fair, but I can't use .Excluding(o => o.FullName) in this case because that would skip assertion all togheter.

I could use .Excluding(o => o.FullName), and write a seperate assertion below it as follows:

output.FullName.Should().Be(fullName);

but that doesn't fix the problem I'm trying to solve, I want every property to be mapped, OR have a specific assertion in BeEquivalentTo so people don't forget to write mappings. And they can still forget to write this seperate assertion when they add .Exluding.

The .WithMapping<Input>() extension method will also not work, since you can assign one property on the input, to another property on the output, but doesn't account for the scenario described above.

IS there a way to do this with Fluent Assertions? That would be my preference since it's already included in the project. Are there anylibraries that tackle this specific scenario, or am I going to have to write this myself?

Thanks!

BartKrul
  • 577
  • 1
  • 8
  • 21

0 Answers0