FluentAssertions技巧:空输入时如何优雅验证属性全为默认值?
问题:FluentAssertions验证对象默认值的更流畅实现方式
我当前通过构建预期匿名对象,使用BeEquivalentTo方法验证OhlcvBuilder在空输入时构建的对象所有属性为默认值。请问FluentAssertions中是否存在更流畅的实现方式?该测试旨在验证无额外输入时Build方法可正常执行且不抛出异常。
测试代码如下:
public class OhlcvBuilderTests { // Happy path [Fact] public void Build_ShouldBeConstructed_WhenGivenEmptyInput() { // Arrange var ohlcvBuilder = new OhlcvBuilder(); var expectedOhlcv = new { Date = DateTimeOffset.MinValue, Open = 0, High = 0, Low = 0, Close = 0, Volume = 0 }; // Act var ohlcv = ohlcvBuilder.Build(); // Assert ohlcv.Should().BeEquivalentTo(expectedOhlcv); } }
回答
当然有更简洁流畅的实现方式,以下几种方案都能避免手动维护匿名预期对象的麻烦:
方案1:链式验证每个属性的默认值
直接针对每个属性验证其等于对应类型的默认值,无需额外创建预期对象,可读性更高:
// Act var ohlcv = ohlcvBuilder.Build(); // Assert ohlcv.Should().NotBeNull(); // 先确保对象实例化成功 ohlcv.Date.Should().Be(default(DateTimeOffset)); ohlcv.Open.Should().Be(default(decimal)); // 根据实际属性类型调整,比如int/long等 ohlcv.High.Should().Be(default(decimal)); ohlcv.Low.Should().Be(default(decimal)); ohlcv.Close.Should().Be(default(decimal)); ohlcv.Volume.Should().Be(default(long));
方案2:使用目标类型的默认实例对比
如果Ohlcv是具体类且无参构造器会生成属性默认值,直接创建默认实例进行等价对比即可:
// Act var ohlcv = ohlcvBuilder.Build(); // Assert ohlcv.Should().BeEquivalentTo(new Ohlcv());
方案3:使用Match方法做内联断言
通过Match方法用Lambda表达式一次性验证所有属性,代码更紧凑:
// Act var ohlcv = ohlcvBuilder.Build(); // Assert ohlcv.Should().Match<Ohlcv>(o => o.Date == default && o.Open == default && o.High == default && o.Low == default && o.Close == default && o.Volume == default);
这些方案的优势在于:当Ohlcv类的属性新增或修改时,不需要同步修改预期对象,减少了测试代码的维护成本,同时保持了断言的流畅性和可读性。另外,只要Build()方法能成功返回对象,就已经验证了“不抛出异常”的核心需求。
内容的提问来源于stack exchange,提问作者Hulkstance
相关产品推荐
相关产品推荐

