Background of the library: Basically I want to compare an object with FluentAssertions BeEquivalentTo
. Now, FluentAssertions Object graph comparison works in a way that is usually good for unit testing: If your source object has additional properties, it does not throw.
In other words: If there are less properties in the target object of the comparison, FluentAssertions will not complain and throw, after all the assertion itself works and all properties you want are in there. The library author has also explained this in this video.
Background of what I want: Now I don't want this, because this integration test, should also catch superfluous properties. Or better: It should catch properties, where I have not yet "written an assertion", i.e. written a target property that I want it to have been compared too. I know this is not test-driven development (TDD)style, but come on, the thing is I have a large object with many sub-properties/objects to compare and I just want to make sure, I have catched and compared/tested all. After all, the test already stands, this is just my last step to "be sure".
Question: So what I actually want for FluentAssertions is that if my target object has a missing property in the source object, it should error/throw.
Here is a MWE:
public class CompareClassTest
{
public class ClassA
{
public int Property1 { get; set; }
public string Property2 { get; set; }
}
public class ClassB
{
public int Property1 { get; set; }
public string Property2 { get; set; }
public bool Property3 { get; set; }
}
[Test]
public void TestEquivalence()
{
var objA = new ClassB
{
Property1 = 1,
Property2 = "Test",
Property3 = true
};
var objB = new ClassA { Property1 = 1, Property2 = "Test" };
objA.Should().BeEquivalentTo(objB
//,
//x => x.ThrowingOnMissingMembers() // -> failed
//,
//options => options
// .IncludingAllDeclaredProperties()
// .IncludingNestedObjects()
// .IncludingAllRuntimeProperties() // -> failed
);
}
}
As you can see above, I have tried some options already. None work.
I also tried asking the AI. As I used JetBrains AI Assistant I have to copy that over and here is the full AI conversation.
It first recommend me wrong methods like ComparingByMembers
. It got a good MWE and I later understood that it was the wrong order around (above is the one which really shows my use case).
Now in the end it got repetitive and said a thing like this would be the only solution:
var responseGetProperties = typeof(ResponseGet).GetProperties().Select(p => p.Name);
var viewModelProperties = typeof(viewModel).GetProperties().Select(p => p.Name);
responseGetProperties.Should().BeEquivalentTo(viewModelProperties);
Edit: Actually for runtime type comparison it should be this:
var responseGetProperties = responseGet.GetType().GetProperties().Select(p => p.Name);
var viewModelProperties = viewModel.GetType().GetProperties().Select(p => p.Name);
responseGetProperties.Should().BeEquivalentTo(viewModelProperties);
However, that also only does a shallow-comparsion and does not go into deep/nested properties.
But really? As FluentAssertions is already iterating properties I would find it unnecessary to do and implement that again? Is not there a simple option
for that that the AI or me may have missed?
Just reversing the order seems to work:
objB.Should().BeEquivalentTo(objA);
DotNetFiddle: https://dotnetfiddle.net/ynvbTp