C# 单元测试 - JSON 上的断言

Posted

技术标签:

【中文标题】C# 单元测试 - JSON 上的断言【英文标题】:C# Unit Testing - Assertions on JSON 【发布时间】:2019-04-26 07:05:05 【问题描述】:

我只是在玩一些 Json 和 Fluentassertions,我能够成功调用 API,获取结果,反序列化它们,但是由于某种原因,当我对响应进行断言时,它会丢失数据它是空的。我已经调试过了,可以看到数据流过,然后在断言过程中丢失。

任何帮助表示赞赏。


    [TestClass]
    public class UnitTest1
    
        HttpClient client = new HttpClient();

         [TestMethod]
        public void ActorNotInSeason6Episode1()
        
            try
            
                //test = extent.CreateTest("Test 1");
                HttpResponseMessage respone = client.GetAsync("https://api.themoviedb.org/3/tv/1399/season/6/episode/1/credits?api_key=").Result;
                Assert.IsTrue(respone.IsSuccessStatusCode.Equals(true));
                string ResponseMessage = respone.Content.ReadAsStringAsync().Result;
                Actors actors = JsonConvert.DeserializeObject<Actors>(ResponseMessage);
                //var a = Actors.cast["cast"];
                //var names = a.Children[];
                //var a = actors.cast.Children();


           actors.cast.Should().Contain("Emilia Clarke", "Test");

            
            catch(AssertFailedException)
            
                Assert.Fail();

            
        

    




    class Actors
    
        public JArray cast   get; set; 
        public JArray guest_stars  get; set; 

    

JSON

[
  
    "character": "Daenerys Targaryen",
    "credit_id": "5256c8af19c2956ff60479f6",
    "gender": 1,
    "id": 1223786,
    "name": "Emilia Clarke",
    "order": 0,
    "profile_path": "/lRSqMNNhPL4Ib1hAJxmDFBXHAMU.jpg"
  
]

【问题讨论】:

显示的 JSON 没有 cast 键。显示的 JSON 是否准确? 当我调用 API 时,演员密钥在那里 "cast": 但 JArray 删除它我相信并只存储上述内容 这听起来不准确。显示的 JSON 与 Actors 对象模型定义不匹配 这是我签入 Postman 时的 JSON:[ "cast":[ "character": "Daenerys Targaryen", "credit_id": "5256c8af19c2956ff60479f6", "gender": 1, "id": 1223786, "name": "Emilia Clarke", "order": 0, "profile_path": "/lRSqMNNhPL4Ib1hAJxmDFBXHAMU.jpg" ] 当我在模型定义中调试和检查 cast 时,它会在没有 "cast": 的情况下存储它 我在浏览器中调用API得到"cast":["character":"Daenerys Targaryen",.... 【参考方案1】:

Here 是 JSON 的 fluentassertions 扩展,它包含许多有用的断言 JSON 的方法:

Available extension methods BeEquivalentTo() ContainSingleElement() ContainSubtree() HaveCount() HaveElement() HaveValue() MatchRegex() NotBeEquivalentTo() NotHaveElement() NotHaveValue() NotMatchRegex()

我不是这个库的作者。

【讨论】:

【参考方案2】:

使用以下基于来自 themoviedb 的预期 JSON 的强类型定义

public partial class RootObject 
    [JsonProperty("cast")]
    public Cast[] Cast  get; set; 

    [JsonProperty("crew")]
    public Crew[] Crew  get; set; 

    [JsonProperty("guest_stars")]
    public Cast[] GuestStars  get; set; 

    [JsonProperty("id")]
    public long Id  get; set; 


public partial class Cast 
    [JsonProperty("character")]
    public string Character  get; set; 

    [JsonProperty("credit_id")]
    public string CreditId  get; set; 

    [JsonProperty("gender")]
    public long Gender  get; set; 

    [JsonProperty("id")]
    public long Id  get; set; 

    [JsonProperty("name")]
    public string Name  get; set; 

    [JsonProperty("order")]
    public long Order  get; set; 

    [JsonProperty("profile_path")]
    public string ProfilePath  get; set; 


public partial class Crew 
    [JsonProperty("id")]
    public long Id  get; set; 

    [JsonProperty("credit_id")]
    public string CreditId  get; set; 

    [JsonProperty("name")]
    public string Name  get; set; 

    [JsonProperty("department")]
    public string Department  get; set; 

    [JsonProperty("job")]
    public string Job  get; set; 

    [JsonProperty("gender")]
    public long Gender  get; set; 

    [JsonProperty("profile_path")]
    public string ProfilePath  get; set; 

您需要在测试中执行以下操作

//...

var actors = JsonConvert.DeserializeObject<RootObject>(ResponseMessage);

//Assert
actors.Cast.Should().Contain(actor => actor.Name == "Emilia Clarke");

【讨论】:

以上是关于C# 单元测试 - JSON 上的断言的主要内容,如果未能解决你的问题,请参考以下文章

JSON 响应断言失败 PHP 单元

单元测试:在设置方法中有断言是一种好习惯吗?

.NET 单元测试的艺术&单元测试之道C#版

模拟 API 响应时如何在单元测试中使用 JSON 文件

Laravel 单元测试显示完全错误

在模拟API响应时,如何在单元测试中使用JSON文件