我已经在我的REST端点集成测试中开始使用FluentAssertions
库。问题是我必须比较两个实体,但要排除它们的_id
属性。该属性是从我的IEntity
界面继承的。
public interface IEntity
{
[BsonId]
ObjectId _id { get; set; }
}
例如Log
类看起来像这样
[DataContract]
public class Log : IEntity
{
[BsonId]
public ObjectId _id { get; set; }
public string Message { get; set; }
}
在测试中,我正在像这样对它们进行比较
retrieved.Should()
.BeEquivalentTo(expected, options => options.Excluding(member => member._id));
但是当我出于扩展目的而将此功能提取到扩展方法中时,它不起作用。它不会忽略_id
成员。
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));
}
}
当我将通用扩展方法更改为特定类型Log
时,它的工作原理就应该如此。
我已经用示例here准备了最小的项目。
有什么方法可以使它正常工作,为什么它不能正常工作?我将尝试在github存储库中检查FluentAssertions
的代码。谢谢。
答案 0 :(得分:1)
首先,在ObjectAssertionsExtensions
中进行更改很有意义
public static void BeEquivalentToExcludingId<TExpectation>(this ObjectAssertions objectAssertion,
TExpectation expectation) where TExpectation : IEntity
到
public static void BeEquivalentToExcludingId(this ObjectAssertions objectAssertion,
IEntity expectation)
我还将每个断言放入单独的测试中以定位问题。
之所以会发生这种情况,是因为BeEquivalentToExcludingId
仅期望IEntity
具有_id
属性,而获得Log
具有额外的Message
属性。这使一切都出错了。如果它不损害您的体系结构,只需将IEntity
属性添加到string Message
即可,它将解决问题。因此,唯一的变化是:
public interface IEntity
{
[BsonId]
ObjectId _id { get; set; }
string Message { get; set; }
}
解决了问题。
更新:
考虑到您的评论,只需将要排除的成员设置为相同的值,调用BeEquivalentTo
并按如下所示设置实际值:
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;
}
这很hack,但是可以。
答案 1 :(得分:1)