如何用FluentAssertions替代TrueForAll?遇常量值预期报错
解决FluentAssertions中使用变量进行范围检查时的"A constant value is expected"错误
我正尝试用FluentAssertions替代Shouldly的.TrueForAll方法,注意旧代码里Products是List<Product>,新代码里是IEnumerable<Product>。但用以下代码时,minPrice和maxPrice会提示"A constant value is expected"错误:
actual.Products.All(x => x.Price is >= minPrice and <= maxPrice).Should().BeTrue(); // A constant value is expected // 或 actual.Products.Should().OnlyContain(x => x.Price is >= minPrice and <= maxPrice); // A constant value is expected
旧代码(Shouldly)
[Theory] [InlineData(10)] [InlineData(12)] [InlineData(5)] public async Task Handle_ReturnsFilteredProductByMaxPrice(double maxPrice) { var parameters = new ProductParams() { MaxPrice = maxPrice }; var result = await _handler.Handle(new GetProductsQuery(parameters), CancellationToken.None); result.Value.Products.TrueForAll(x => x.Price <= maxPrice); }
新代码(FluentAssertions,存在错误)
[Theory] [InlineData(10, 14)] [InlineData(22, 24)] public async Task Handle_ShouldReturnFilteredSubsetOfProducts_WhenGivenMinPriceAndMaxPrice(double minPrice, double maxPrice) { // Arrange var query = new GetProductsQuery(MinPrice: minPrice, MaxPrice: maxPrice); // Act var actual = await _queryHandler.Handle(query, default); // Assert actual.Products.All(x => x.Price is >= minPrice and <= maxPrice).Should().BeTrue(); }
Product定义
public record Product( [property: JsonPropertyName("title")] string Title, [property: JsonPropertyName("price")] double Price, [property: JsonPropertyName("sizes")] List<string> Sizes, [property: JsonPropertyName("description")] string Description);
解决方法
这个错误是因为使用了C#的关系模式匹配语法(is >= minPrice),而FluentAssertions在解析表达式树时,要求关系模式的右侧必须是常量值。换成普通的比较运算符写法即可解决:
修正后的断言代码
第一种方式(结合All和Should().BeTrue()):
actual.Products.All(x => x.Price >= minPrice && x.Price <= maxPrice).Should().BeTrue();
第二种方式(使用FluentAssertions内置的OnlyContain):
actual.Products.Should().OnlyContain(x => x.Price >= minPrice && x.Price <= maxPrice);
原因说明
关系模式(is >= value)是C# 9.0引入的语法,当用于表达式树(比如FluentAssertions用来解析断言条件的场景)时,对变量的支持有限;而传统的比较运算符(>=、<=、&&)在表达式树中可以正常引用测试方法的参数变量,不会受常量值的限制。
内容的提问来源于stack exchange,提问作者nop
相关产品推荐
相关产品推荐

