如何在Fluent Assertions中断言同名不同类型的属性?
问题:自动验证日期字符串与可空DateTime的等价性
当断言不同类型的属性时,会收到如下预期错误:Expected property a.Date to be System.String, but found System.DateTime.
我希望无需手动逐个断言,就能验证日期字符串与可空DateTime的相等性。由于需断言的属性数量较多,我更倾向于指定某种规则或关联关系,而非先将这些属性从BeEquivalentTo中排除,再逐个使用a.DateX.Should().Be(b.DateX.ToNullableDateTime());进行断言。
问题演示示例
[TestFixture] public class MyTests { [Test] public void ShouldMapDates() { //Arrange var b = new B { Date = "01.01.0001" }; //Act var a = B.MapToA(b); //Assert a.Should().BeEquivalentTo(b, c => { // 这里需要配置规则? }); } } public class A { public DateTime? Date { get; set; } } public class B { public string Date { get; set; } public static A MapToA(B b) { return new A { Date = b.Date.ToNullableDateTime() }; } }
我已有可用的ToNullableDateTime扩展方法,也具备将DateTime?转换回相同字符串格式的扩展方法,当前使用Fluent Assertions v6.11版本。
解决方法
通过自定义IEquivalencyStep实现自定义等价性验证逻辑:
public class DateEqualityStep : IEquivalencyStep { public EquivalencyResult Handle(Comparands comparands, IEquivalencyValidationContext context, IEquivalencyValidator nestedValidator) { if (context.CurrentNode.IsRoot) { return EquivalencyResult.ContinueWithNext; } if (comparands.Subject?.GetType() != typeof(DateTime) || comparands.RuntimeType != typeof(string)) { return EquivalencyResult.ContinueWithNext; } var subject = (DateTime?)comparands.Subject; var expectation = (string)comparands.Expectation; subject.Should().Be(expectation.ToNullableDateTime(), context.Reason.FormattedMessage, context.Reason.Arguments); return EquivalencyResult.AssertionCompleted; } }
使用方式
a.Should().BeEquivalentTo(b, c => c.Using(new DateEqualityStep()));
这种方式足以满足我的场景需求。
内容的提问来源于stack exchange,提问作者Vidar Flesjø
相关产品推荐
相关产品推荐

