I have started using FluentAssertions
library in my integration tests for the REST endpoints. The problem is I have to compare two entities, but excluding their _id
properties. This property is being inherited from my IEntity
interface.
public interface IEntity
{
[BsonId]
ObjectId _id { get; set; }
}
So for example Log
class looks like this
[DataContract]
public class Log : IEntity
{
[BsonId]
public ObjectId _id { get; set; }
public string Message { get; set; }
}
In the test I am comparing them like this and it works
retrieved.Should()
.BeEquivalentTo(expected, options => options.Excluding(member => member._id));
But when I extract this functionality to extension method for reuse purposes, it does not work. It does not ignore the _id
member.
public static class ObjectAssertionExtensions
{
public static void BeEquivalentToExcludingId<TExpectation>(this ObjectAssertions objectAssertion, TExpectation expectation) where TExpectation : IEntity
{
objectAssertion.BeEquivalentTo(expectation, options => options.Excluding(member => member._id));
}
}
When I change the generic extension method to a specific type Log
, then it works like it should. I have prepared minimal project with example here . Is there a way how to get this working please and why does it not work properly? I will try to check the code of FluentAssertions
in github repository. Thanks.
First of all, in ObjectAssertionsExtensions
it makes sense to change
public static void BeEquivalentToExcludingId<TExpectation>(this ObjectAssertions objectAssertion,
TExpectation expectation) where TExpectation : IEntity
to
public static void BeEquivalentToExcludingId(this ObjectAssertions objectAssertion,
IEntity expectation)
I'd also put each assertion into separate test to localize the problem.
The thing happens because BeEquivalentToExcludingId
expects IEntity
with _id
property only, but gets Log
with extra Message
property. That makes everything go wrong. If it doesn't harm your architecture just ammend IEntity
with string Message
property and it will fix the thing. So, the only change:
public interface IEntity
{
[BsonId]
ObjectId _id { get; set; }
string Message { get; set; }
}
solves the problem.
Update:
Taking into account your comment, just set members to exclude to the same value, call BeEquivalentTo
and set actual values back like this:
public static void BeEquivalentToExcludingId(this ObjectAssertions objectAssertion, IEntity expectation)
{
var subj = (IEntity)objectAssertion.Subject;
var subjId = subj._id;
var expId = expectation._id;
subj._id = ObjectId.Empty;
expectation._id = ObjectId.Empty;
objectAssertion.BeEquivalentTo(expectation);
subj._id = subjId;
expectation._id = expId;
}
It's hacky, but it works.
The problem is that Fluent Assertions fails to correlate _id
of the generic type T
to _id
of the concrete type Log
.
A similar issue was reported in #1077 and resolved with #1087 . As of writing we haven't released new version containing this fix.
Edit 2019-08-10:
Fluent Assertions 5.8.0 has been released with the fix.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.