Fluent Assertions 6 不同成员类型名称的集合比较方案问询
Fluent Assertions 6+ 异成员集合等价比较方案
Fluent Assertions 6之后官方已经简化了这类成员类型、名称不匹配的集合等价比较逻辑,不需要再自行实现IEquivalencyStep接口,以下是三种常用的可行方案:
方案1:单次断言配置映射规则
适合仅单次需要比较的场景,直接在断言语句中指定成员对应关系即可:
假设你需要比较的两个集合的元素类型定义如下:
// 源集合元素类型 public class SourceItem { public int Id { get; set; } public string SourceName { get; set; } public DateTime CreateTime { get; set; } } // 目标集合元素类型 public class TargetItem { public long ItemId { get; set; } public string TargetName { get; set; } public long CreateTimestamp { get; set; } }
断言写法:
List<SourceItem> sourceList = GetSourceList(); List<TargetItem> targetList = GetTargetList(); sourceList.Should().BeEquivalentTo(targetList, options => options // 映射Id和ItemId(自动兼容int和long的类型差异) .For<SourceItem>(src => src.Compare(x => x.Id).To<TargetItem>(tgt => tgt.ItemId)) // 映射SourceName和TargetName .For<SourceItem>(src => src.Compare(x => x.SourceName).To<TargetItem>(tgt => tgt.TargetName)) // 自定义时间和时间戳的转换逻辑 .For<SourceItem>(src => src.Compare(x => x.CreateTime).To<TargetItem>(tgt => DateTimeOffset.FromUnixTimeMilliseconds(tgt.CreateTimestamp).DateTime )) );
方案2:全局注册类型映射规则
如果多处测试都需要用到同一组类型的比较规则,可以全局注册映射,避免重复写配置:
// 全局测试初始化时执行一次即可 AssertionOptions.DefaultEquivalencyPlan.Add<SourceItem, TargetItem>(map => map .Map(src => src.Id, tgt => tgt.ItemId) .Map(src => src.SourceName, tgt => tgt.TargetName) .Map(src => src.CreateTime, tgt => DateTimeOffset.FromUnixTimeMilliseconds(tgt.CreateTimestamp).DateTime) );
后续断言时不需要再额外配置:
sourceList.Should().BeEquivalentTo(targetList);
方案3:自定义比较委托处理复杂场景
如果成员对应逻辑非常复杂,用配置方式难以实现,可以直接指定自定义比较逻辑:
sourceList.Should().BeEquivalentTo(targetList, options => options .Using<object>(ctx => { var source = ctx.Subject as SourceItem; var target = ctx.Expectation as TargetItem; // 这里可以写任意自定义比较逻辑 source.Id.Should().Be((int)target.ItemId); source.SourceName.Should().Be(target.TargetName); source.CreateTime.Should().BeCloseTo( DateTimeOffset.FromUnixTimeMilliseconds(target.CreateTimestamp).DateTime, TimeSpan.FromSeconds(1) ); }) .When((subject, expectation) => subject is SourceItem && expectation is TargetItem) );
内容的提问来源于stack exchange,提问作者rgb
相关产品推荐
相关产品推荐

