【问题标题】:C# HttpClient - GET - Parse response and assertC# HttpClient - GET - 解析响应并断言
【发布时间】:2021-04-05 11:57:02
【问题描述】:

我正在使用 HttpClient 进行 GET 调用,我想解析 Json 响应并断言键值对

这是我的代码

public partial class EntityClass
{
    [JsonProperty("StatusCode")]
    public string StatusCode { get; set; }

    // more code
}

using (HttpClientHandler handler = new HttpClientHandler())
            {
                handler.Credentials = new NetworkCredential(@"Domain\user", "password");
                using (HttpClient client = new HttpClient(handler))
                {
                    client.BaseAddress = new Uri("https://baseURL");
                    client.DefaultRequestHeaders.Accept.Clear();
                    HttpResponseMessage response = await client.GetAsync("api/apiendpoint")
                    response.EnsureSuccessStatusCode();

                    string responsebody = response.Content.ReadAsStringAsync().Result;
                    var data = JsonConvert.DeserializeObject<EntityClass>(responsebody);
                    
                }
            }

我可以这样断言响应

Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);

但是,我想在 Json 响应中声明每个键值对。我不能让它与上面的代码一起工作 如何访问键值对和断言?

例如,如果 Json 响应是:

{
StatusCode:200,
Key1: Value1,
Key2: Value2
}

我希望能够断言喜欢

Assert.AreEqual(200,data.StatusCode);
Assert.AreEqual(Value1, data.Key1);
Assert.AreEqual(Value2, data.Key2);

但是在我的代码 response.StatusCode 中返回 OK 而不是 200

【问题讨论】:

  • 代码中的“responsebody”将不包含响应代码。响应代码是 HttpResponseMessage 的属性,而不是 HttpResponseMessage.Content。您可以在反序列化调用创建其余部分后手动添加它。
  • 你想断言从json解析的对象的属性具有特定的值(什么属性和什么值?)或者你想将HttpResponseMessage转换为json并断言一些属性和值(哪些?)在那?
  • @ZdeněkJelínek 例如,如果响应是 {StatusCode: 200, Key1: Value, Key2: Value} 我希望能够根据要求分别声明每个值
  • @ZdeněkJelínek 我添加了更多细节。当我断言 response.StatusCode 值是 OK 而不是 200
  • 根据您的编辑:HttpResponse 上没有 Value1Value2 属性。你确定你的最后一个代码 sn-p 不应该包含 data 而不是 response 吗?因为data 是解析后的响应json 正文,而response 是抽象的HTTP 响应,恰好也有StatusCode 属性。

标签: c# asp.net api automation httpclient


【解决方案1】:

正如评论者所说,状态代码不是正文的一部分,但您似乎正确处理了该部分。

要在调用时获取键/值对,可以将字符串解析为中间表示,然后迭代该表示的属性。这避免了必须具有通常会填充的本机 .NET 类型,这可能更可取以避免自动化测试依赖于特定类型。

所以,这取决于您可以或必须使用哪个序列化程序。由于我在您的代码中看到JsonConvert,因此您正在使用 Newtonsoft 的代码。在这种情况下使用JObject.Parse():

using Newtonsoft.Json.Linq;
...
var expectedValues = new Dictionary<string, object>();
var responsebody = response.Content.ReadAsStringAsync().GetAwaiter().GetResult();
var root = JObject.Parse(responsebody);

foreach (var property in root.Properties)
{
    // not tested, but you get the idea...
    var expectedValue = expectedValues[property.Name];
    if (expectedValue == null)
        // null has to be checked via token type
        Assert.IsTrue(property.Value.Type == JTokenType.Null);
    else
        // check they are same type AND value
        Assert.AreEqual(property.Value.ToObject(expectedValue.GetType()), expectedValue);
}

这里的技巧是,您需要创建一个字典,将预期的键映射到预期的值,然后根据中间表示中的内容检查这些值。 这可以用来证明输出中没有意外的键(因为没有字典条目),并证明对于返回的键,它们的值是预期的。

为了同时证明没有丢失键,您可以根据返回的属性名称检查字典的键。

【讨论】:

  • 是否可以添加导入语句?
  • 我不知道所有这些,但添加了 Newtonsoft。
  • 没有导入语句和(过度?)使用“var”的问题......这使得复制和粘贴“工作”代码变得更加困难。 #just说
  • @granadaCoder SO 不是代码编写服务,使用var 是一场没有人会赢的宗教战争。就像在所有编程中一样,有一些权衡和非常酷的方法可以让自己在脚下开枪。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-11-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-28
  • 1970-01-01
相关资源
最近更新 更多