在 FluentAssertions.Primitives.ObjectAssertions 的扩展方法中调用 Excluding 方法不起作用,但调用它正常工作
Calling Excluding method in extension method for FluentAssertions.Primitives.ObjectAssertions does not work, but calling it normally works
我已经开始在 REST 端点的集成测试中使用 FluentAssertions
库。问题是我必须比较两个实体,但不包括它们的 _id
属性。这个 属性 是从我的 IEntity
接口继承的。
public interface IEntity
{
[BsonId]
ObjectId _id { get; set; }
}
例如 Log
class 看起来像这样
[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
的代码。谢谢。
首先,在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;
}
它很笨拙,但它确实有效。
问题是 Fluent Assertions 无法将通用类型 T
的 _id
关联到具体类型 Log
的 _id
。
#1077 and resolved with #1087 中报告了类似的问题。
在撰写本文时,我们尚未发布包含此修复程序的新版本。
编辑 2019-08-10:
Fluent Assertions 5.8.0 已随修复发布。
我已经开始在 REST 端点的集成测试中使用 FluentAssertions
库。问题是我必须比较两个实体,但不包括它们的 _id
属性。这个 属性 是从我的 IEntity
接口继承的。
public interface IEntity
{
[BsonId]
ObjectId _id { get; set; }
}
例如 Log
class 看起来像这样
[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
的代码。谢谢。
首先,在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;
}
它很笨拙,但它确实有效。
问题是 Fluent Assertions 无法将通用类型 T
的 _id
关联到具体类型 Log
的 _id
。
#1077 and resolved with #1087 中报告了类似的问题。 在撰写本文时,我们尚未发布包含此修复程序的新版本。
编辑 2019-08-10:
Fluent Assertions 5.8.0 已随修复发布。