Fluent Assertion 中的对象结构比较方法

Posted

技术标签:

【中文标题】Fluent Assertion 中的对象结构比较方法【英文标题】:Object structure comparison methods in Fluent Assertion 【发布时间】:2019-07-19 13:52:20 【问题描述】:

我注意到最新的 nuget 包(FluentAssertions -Version 5.6.0)我仍然看不到 ShouldBeEquivalentTo 方法来进行没有价值的对象比较(仅结构)。我可以看到Should().BeEquivalentTo(),但不知道如何断言除值之外的对象结构。

我的解决方案是.Net Core 2.1

我的代码:

[Fact]
        public void GetFlatTariffForOneProduct_ReturnSuccess()
        
            this.Given(_ => _steps.GivenACorrelationIdHeaderIsProvided(true))
                .And(_ => _steps.TheFlatTariffRawDataInDb(1))
                .When(_ => _steps.WhenTheRequestExecutes(_endpoint, new EstimationRequestBuilder().FlatRateElecRequest().Build()))
                .Then(_ => _steps.TheResponseCodeIs(HttpStatusCode.OK))
                .And(_ => _steps.TheReturnedContentIs(new EstimationResponseBuilder().EstimateResponse(1).Build()))
                .BDDfy();
        

上面的最后一步调用下面的方法来断言没有数据的对象模型。

public async Task TheReturnedContentIs<T>(T obj)
        
            var responseString = await ResponseMessage.Content.ReadAsStringAsync();
            var deserializeObject = JsonConvert.DeserializeObject<T>(responseString);
            obj.Should().BeEquivalentTo(deserializeObject);

        

预期响应:


    "attributeA": 
        "attribute2": "CITIPP",
        "attribute3": [
            
                "attribute4": "Variable",
                "attribute5": 
                    "attribute6": 65.5022916666667,
                    "attribute7": 45.407291666666673,
                    "attribute8": 33.454791666666679
                
            ,
            
                "attribute4": "Fixed",
                "attribute5": 
                    "attribute6": 21.8762916666667,
                    "attribute7": 89.432291666666673,
                    "attribute8": 90.236791666666679
                
            
        ]
    ,
    "attributeB": 
        "attribute2": "CITIPP",
        "attribute3": [
            
                "attribute4": "Variable",
                "attribute5": 
                    "attribute6": 71.5022916666667,
                    "attribute7": 53.407291666666673,
                    "attribute8": 62.454791666666679
                
            ,
            
                "attribute4": "Fixed",
                "attribute5": 
                    "attribute6": 38.5022916666667,
                    "attribute7": 53.407291666666673,
                    "attribute8": 44.3684791666666679
                
            
        ]
    

使用下面的断言,实际响应应该通过。正如您所注意到的,结构与值相同。但是,如果任何 attribute 名称不同,则断言应该失败。 (例如,如果 attributeA 在响应中更改为 attributeX

实际反应


    "attributeA": 
        "attribute2": "ABCD",
        "attribute3": [
            
                "attribute4": "Variable",
                "attribute5": 
                    "attribute6": 71.5022916666667,
                    "attribute7": 53.407291666666673,
                    "attribute8": 62.454791666666679
                
            ,
            
                "attribute4": "Fixed",
                "attribute5": 
                    "attribute6": 71.5022916666667,
                    "attribute7": 53.407291666666673,
                    "attribute8": 62.454791666666679
                
            
        ]
    ,
    "attributeB": 
        "attribute2": "CITIPP",
        "attribute3": [
            
                "attribute4": "Variable",
                "attribute5": 
                    "attribute6": 54.5022916666667,
                    "attribute7": 11.407291666666673,
                    "attribute8": 98.454791666666679
                
            ,
            
                "attribute4": "Fixed",
                "attribute5": 
                    "attribute6": 71.222916666667,
                    "attribute7": 53.33291666666673,
                    "attribute8": 32.454791666666679
                
            
        ]
    

我将对象模型传递给上述方法。所以我希望比较没有值的对象结构。由于值差异导致上述断言失败的原因。结构完美匹配。

【问题讨论】:

ShouldBeEquivalentTo 已在 v5.0.0 中删除 continuousimprover.com/2018/02/… 有关具体比较问题的帮助,请发帖 Minimal, Complete, and Verifiable example 它与这个obj.Should().Equals(deserializeObject); 一起工作。不知道有没有更好的东西。 obj.Should().Equals() 不解析为Object.Equals(object) @JonasNyrup 确实如此。 那你不再断言什么了? 【参考方案1】:

您可以做的是像BeEquivalentTo 通常那样遍历两个对象图,但是通过将任意两个实例视为相等来忽略所有字符串和数字类型。

这是一个应该这样做的示例。

T expected = JsonConvert.DeserializeObject<T>(expectedJSON);
T actual = JsonConvert.DeserializeObject<T>(actualJSON);

actual.Should().BeEquivalentTo(expected, opt => opt
    .Using<object>(_ =>  )
    .When(e => e.RuntimeType.IsValueType)
    .Using<string>(_ =>  )
    .WhenTypeIs<string>())

在文档中阅读更多信息:https://fluentassertions.com/objectgraphs/#equivalency-comparison-behavior

【讨论】:

以上是关于Fluent Assertion 中的对象结构比较方法的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Fluent Assertion 比较两个因属性而异的集合?

如何检查是不是可以在 Fluent Assertion 中使用 ContainValue 验证类型类的字典

Fluent-bit - 将 json 日志拆分为 Elasticsearch 中的结构化字段

ShouldBeEquivalentTo 的 C# Fluent Assertions 全局选项

fluent模拟结果中的传热系数怎么求

Fluent Assertions Should().BeEquivalentTo 只有私有字段