如何用FluentAssertions测试所有属性均已修改(无目标值限制)
解决方案:用FluentAssertions断言所有属性均与原状态不同
要实现所有属性都必须被修改(即每个属性值都与原对象的对应属性不同),你可以利用FluentAssertions的自定义成员验证逻辑,替代默认的等价性检查。
核心实现代码
通过BeEquivalentTo结合Using和ForAllMembers,为每个成员指定“不等于原对象对应值”的验证规则:
after.Should().BeEquivalentTo(before, options => options.Using<object>(ctx => ctx.Subject.Should().NotBe(ctx.Expectation)) .ForAllMembers());
代码解释
BeEquivalentTo(before):启动对象图等价性比较的基础框架Using<object>(...):定义针对所有成员的自定义验证逻辑,要求当前成员的值(ctx.Subject)不等于原对象的对应成员值(ctx.Expectation)ForAllMembers():将这个自定义规则应用到所有属性/字段上
适配你的测试案例
修改你提供的测试代码,用上述断言替换原来的NotBeEquivalentTo:
[Test] public void ShouldFail_BecauseClassesAreEquivalent() { var before = new MyClass { Apple = 1, Banana = 2 }; var after = new MyClass2 { Apple = 1, Banana = 2 }; // 所有属性都未修改,断言失败(符合预期) after.Should().BeEquivalentTo(before, options => options.Using<object>(ctx => ctx.Subject.Should().NotBe(ctx.Expectation)) .ForAllMembers()); } [Test] public void ShouldFail_BecauseClassesShouldHaveALlPropertiesModified_NotOnlyOne() { var before = new MyClass { Apple = 1, Banana = 2 }; var after = new MyClass2 { Apple = 100, Banana = 2 }; // Banana属性未修改,断言失败(符合预期) after.Should().BeEquivalentTo(before, options => options.Using<object>(ctx => ctx.Subject.Should().NotBe(ctx.Expectation)) .ForAllMembers()); } [Test] public void ShouldWork_BecauseClassesDoHaveALlPropertiesModified() { var before = new MyClass { Apple = 1, Banana = 2 }; var after = new MyClass2 { Apple = 100, Banana = 200 }; // 所有属性都已修改,断言通过(符合预期) after.Should().BeEquivalentTo(before, options => options.Using<object>(ctx => ctx.Subject.Should().NotBe(ctx.Expectation)) .ForAllMembers()); }
扩展:验证对象所有属性已被填充(与空状态对比)
针对你提到的“检查对象所有属性均已被填充”的场景,只需将原对象替换为空实例即可:
var emptyState = new MyClass2(); after.Should().BeEquivalentTo(emptyState, options => options.Using<object>(ctx => ctx.Subject.Should().NotBe(ctx.Expectation)) .ForAllMembers());
这样就能确保每个属性都不再是默认值(比如int类型的0),达到“所有属性已被填充”的验证目的。
注意事项
- 该方案仅验证属性值与原状态不同,无法检测属性映射错误(比如把Apple的值映射到Banana),这部分如你所说,可通过代码评审覆盖
- 如果需要针对特定类型做特殊处理(比如引用类型的null检查),可以修改
Using的泛型类型并调整验证逻辑
内容的提问来源于stack exchange,提问作者rklec
相关产品推荐
相关产品推荐

