You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

515 lines
17 KiB
C#

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net.Http.Json;
using System.Net;
using Newtonsoft.Json;
using Microsoft.AspNetCore.Mvc;
using System.Text.Json;
using System.Security.Authentication.ExtendedProtection;
using Newtonsoft.Json.Linq;
using System.Text.Json.Serialization.Metadata;
namespace HttpClientStudy.UnitTest
{
/// <summary>
/// 基础HttpClient 测试
/// </summary>
public class NormalHttpClientTest
{
private readonly ITestOutputHelper _logger;
public NormalHttpClientTest(ITestOutputHelper outputHelper)
{
_logger = outputHelper;
}
#region GET请求
[Fact]
public async Task GetAllAccounts_Test()
{
HttpClient httpClient = new HttpClient()
{
BaseAddress = new Uri(TestConfig.WebApiBaseUrl),
};
var responseMessage = await httpClient.GetAsync("/api/Normal/GetAllAccounts");
responseMessage.EnsureSuccessStatusCode();
Assert.NotNull(responseMessage);
Assert.True(responseMessage.IsSuccessStatusCode);
var result = await responseMessage.Content.ReadFromJsonAsync<BaseResult<List<Account>>>();
Assert.IsType<BaseResult<List<Account>>>(result);
Assert.Equal(1, result.Code);
Assert.NotNull(result.Data);
}
/// <summary>
/// GET 请求
/// (默认参数方式url传参)
/// </summary>
/// <returns></returns>
[Fact]
public async Task GetAccount_Id_Test()
{
HttpClient httpClient = new HttpClient()
{
BaseAddress = new Uri(TestConfig.WebApiBaseUrl),
};
var responseMessage = await httpClient.GetAsync("/api/Normal/GetAccount?Id=2");
responseMessage.EnsureSuccessStatusCode();
Assert.NotNull(responseMessage);
Assert.True(responseMessage.IsSuccessStatusCode);
var result = await responseMessage.Content.ReadFromJsonAsync<BaseResult<Account>>();
Assert.IsType<BaseResult<Account>>(result);
Assert.Equal(1, result.Code);
Assert.Equal(2, result.Data?.Id);
}
/// <summary>
/// GET 请求
/// (路由传参)
/// </summary>
/// <returns></returns>
[Fact]
public async Task GetAccount_Route_Test()
{
HttpClient httpClient = new HttpClient()
{
BaseAddress = new Uri(TestConfig.WebApiBaseUrl),
};
var responseMessage = await httpClient.GetAsync("/api/Normal/GetAccount/管理员02");
responseMessage.EnsureSuccessStatusCode();
Assert.NotNull(responseMessage);
Assert.True(responseMessage.IsSuccessStatusCode);
var result = await responseMessage.Content.ReadFromJsonAsync<BaseResult<Account>>();
Assert.IsType<BaseResult<Account>>(result);
Assert.Equal(1, result.Code);
Assert.Equal("管理员02", result.Data?.Name);
}
/// <summary>
/// GET 请求
/// (中文参数:现在浏览器直接支持,为最大兼容老旧浏览器使用url编码)
/// </summary>
/// <returns></returns>
[Fact]
public async Task GetAccountByName_Test()
{
HttpClient httpClient = new HttpClient()
{
BaseAddress = new Uri(TestConfig.WebApiBaseUrl),
};
var ChineseName = System.Net.WebUtility.UrlEncode("管理员01");
var ChineseName2 = System.Net.WebUtility.UrlEncode("管理员02");
//现在浏览器直接支持中文参数
//var responseMessage = await httpClient.GetAsync("/api/Normal/GetAccountByName?ChineseName=管理员01&ChineseName2=管理员02");
//兼容老浏览器写法
var responseMessage = await httpClient.GetAsync($"/api/Normal/GetAccountByName?ChineseName={ChineseName}&ChineseName2={ChineseName2}");
responseMessage.EnsureSuccessStatusCode();
Assert.NotNull(responseMessage);
Assert.True(responseMessage.IsSuccessStatusCode);
var result = await responseMessage.Content.ReadFromJsonAsync<BaseResult<List<Account>>>();
Assert.IsType<BaseResult<List<Account>>>(result);
Assert.Equal(1, result.Code);
Assert.Equal(2, result.Data?.Count);
}
/// <summary>
/// GET 请求
/// (查询参数传参)
/// </summary>
/// <returns></returns>
[Fact]
public async Task GetAccountByRole_Test()
{
HttpClient httpClient = new HttpClient()
{
BaseAddress = new Uri(TestConfig.WebApiBaseUrl),
};
var responseMessage = await httpClient.GetAsync("/api/Normal/GetAccountByRole?role=Admin");
responseMessage.EnsureSuccessStatusCode();
Assert.NotNull(responseMessage);
Assert.True(responseMessage.IsSuccessStatusCode);
var result = await responseMessage.Content.ReadFromJsonAsync<BaseResult<List<Account>>>();
Assert.IsType<BaseResult<List<Account>>>(result);
Assert.Equal(1, result.Code);
//每项的角色都是查询的角色
Assert.False(result.Data?.Any(d=>d.Role != "Admin"));
}
/// <summary>
/// GET 请求
/// (请求头传参中文必须Url编码,服务端Url解码后使用)
/// </summary>
/// <returns></returns>
[Fact]
public async Task GetAccountFromHeader_Test()
{
HttpClient httpClient = new HttpClient()
{
BaseAddress = new Uri(TestConfig.WebApiBaseUrl),
};
//中文参数必须先编码
httpClient.DefaultRequestHeaders.Add("name", System.Net.WebUtility.UrlEncode("管理员01"));
var responseMessage = await httpClient.GetAsync("/api/Normal/GetAccountFromHeader");
responseMessage.EnsureSuccessStatusCode();
Assert.NotNull(responseMessage);
Assert.True(responseMessage.IsSuccessStatusCode);
var result = await responseMessage.Content.ReadFromJsonAsync<BaseResult<Account>>();
Assert.IsType<BaseResult<Account>>(result);
Assert.Equal(1, result.Code);
Assert.Equal(1,result.Data?.Id);
}
/// <summary>
/// GET 请求
/// (客户端不传参服务端参数直接来由IoC中注入的服务)
/// </summary>
/// <returns></returns>
[Fact]
public async Task GetAccountByService_Test()
{
HttpClient httpClient = new HttpClient()
{
BaseAddress = new Uri(TestConfig.WebApiBaseUrl),
};
var responseMessage = await httpClient.GetAsync("/api/Normal/GetAccountFromServices");
responseMessage.EnsureSuccessStatusCode();
Assert.NotNull(responseMessage);
Assert.True(responseMessage.IsSuccessStatusCode);
var result = await responseMessage.Content.ReadFromJsonAsync<BaseResult<Account>>();
Assert.IsType<BaseResult<Account>>(result);
Assert.Equal(1, result.Code);
Assert.Equal("服务注入示例",result.Data?.Name);
}
/// <summary>
/// GET 请求
/// (直接调用System.Net.Http.Json类的扩展方法GetFromJsonAsync 获取 Json 结果)
/// </summary>
/// <returns></returns>
[Fact]
public async Task Get_From_Json_Test()
{
HttpClient httpClient = new HttpClient()
{
BaseAddress = new Uri(TestConfig.WebApiBaseUrl),
};
var result = await httpClient.GetFromJsonAsync<BaseResult<Account>>("/api/Normal/GetAccountFromServices");
Assert.IsType<BaseResult<Account>>(result);
Assert.Equal(1, result.Code);
Assert.Equal("服务注入示例", result.Data?.Name);
}
#endregion
#region PUT 请求
/// <summary>
/// Put 请求
/// (新建或替换、更新资源)
/// </summary>
/// <returns></returns>
[Fact]
public async Task PutDemo_Test()
{
HttpClient httpClient = new HttpClient()
{
BaseAddress = new Uri(TestConfig.WebApiBaseUrl),
};
var responseMessage = await httpClient.PutAsync("/api/Normal/PutDemo?id=2",null);
responseMessage.EnsureSuccessStatusCode();
Assert.NotNull(responseMessage);
Assert.True(responseMessage.IsSuccessStatusCode);
var result = await responseMessage.Content.ReadAsStringAsync();
}
#endregion
#region HEAD 请求
/// <summary>
/// Head 请求
/// 注意HttpClient没有直接提供HEAD请求方法
/// 步骤1构建 HttpRequestMessage 对象设置HttpMethod.Head
/// 步骤2把上步构建的HttpRequestMessage 对象,作为参数传递给 HttpClient实例的 Send 或 SendAsync 方法
/// </summary>
/// <returns></returns>
[Fact]
public async Task HeadDemo_Test()
{
HttpClient httpClient = new HttpClient()
{
BaseAddress = new Uri(TestConfig.WebApiBaseUrl),
};
var requestMessage = new HttpRequestMessage(HttpMethod.Head, "/api/Normal/HeadDemo?Id=2");
HttpResponseMessage responseMessage = await httpClient.SendAsync(requestMessage);
responseMessage.EnsureSuccessStatusCode();
Assert.NotNull(responseMessage);
Assert.True(responseMessage.IsSuccessStatusCode);
//head请求没有返回体
var result = await responseMessage.Content.ReadAsStringAsync();
Assert.Empty(result);
}
#endregion
#region POST 请求
[Fact]
public async Task PostSimple_Test()
{
HttpClient httpClient = new HttpClient()
{
BaseAddress = new Uri(TestConfig.WebApiBaseUrl),
};
//响应
var responseMessage = await httpClient.PostAsync("/api/Normal/PostSimple", null);
//响应正常
Assert.True(responseMessage.IsSuccessStatusCode);
Assert.NotNull(responseMessage);
var result = await responseMessage.Content.ReadFromJsonAsync<BaseResult<string>>();
Assert.IsType<BaseResult<string>>(result);
Assert.Equal(1, result?.Code);
}
[Fact]
public async Task PostCreate_Test()
{
HttpClient httpClient = new HttpClient()
{
BaseAddress = new Uri(TestConfig.WebApiBaseUrl),
};
//参数
var para = new Account() {Id=100, Name="小明", Password="123456", Role="Admin" };
//请求体
var plainContent = new StringContent(JsonConvert.SerializeObject(para), Encoding.UTF8, System.Net.Mime.MediaTypeNames.Application.Json);
//发POST请求
var responseMessage = await httpClient.PostAsync("/api/Normal/PostCreate", plainContent);
//确保响应正常
responseMessage.EnsureSuccessStatusCode();
Assert.NotNull(responseMessage);
Assert.True(responseMessage.IsSuccessStatusCode);
var text = await responseMessage.Content.ReadAsStringAsync();
var result = JsonConvert.DeserializeObject<CreatedAtActionResult> (text);
Assert.IsType<CreatedAtActionResult>(result);
Assert.Equal(201, result.StatusCode);
Assert.IsType<Newtonsoft.Json.Linq.JObject>(result.Value);
//新创建的对象
var account = JsonConvert.DeserializeObject<Account>(value: result.Value.ToString() ?? "");
Assert.NotNull(account);
Assert.Equal(100,account.Id);
//由于构造函数等原因直接使用ReadFromJsonAsync会异常。
//CreatedAtActionResult? result = await responseMessage.Content.ReadFromJsonAsync<CreatedAtActionResult>(new JsonSerializerOptions() { IncludeFields=true, PropertyNameCaseInsensitive=true});
}
[Fact]
public async Task PostUpdate_Test()
{
HttpClient httpClient = new HttpClient()
{
BaseAddress = new Uri(TestConfig.WebApiBaseUrl),
};
//参数
var para = new Account() { Id = 1, Name = "小明", Password = "123456", Role = "Admin" };
//发POST请求
var responseMessage = await httpClient.PostAsJsonAsync("/api/Normal/PostUpdate", para);
//确保响应正常
responseMessage.EnsureSuccessStatusCode();
Assert.NotNull(responseMessage);
Assert.True(responseMessage.IsSuccessStatusCode);
var result = await responseMessage.Content.ReadFromJsonAsync<BaseResult<Account>>();
Assert.IsType<BaseResult<Account>>(result);
Assert.Equal(1, result.Code);
Assert.Equal(1, result.Data?.Id);
}
[Fact]
public async Task PostRemove_Test()
{
HttpClient httpClient = new HttpClient()
{
BaseAddress = new Uri(TestConfig.WebApiBaseUrl),
};
var para_id = 2;
//发POST请求(URL传参)
var responseMessage = await httpClient.PostAsync($"/api/Normal/PostRemove?Id={para_id}", null);
//确保响应正常
responseMessage.EnsureSuccessStatusCode();
Assert.NotNull(responseMessage);
Assert.True(responseMessage.IsSuccessStatusCode);
var result = await responseMessage.Content.ReadFromJsonAsync<BaseResult<Account>>();
Assert.IsType<BaseResult<Account>>(result);
Assert.Equal(1, result.Code);
Assert.Equal(para_id, result.Data?.Id);
}
#endregion
#region DELETE 请求
[Fact]
public async Task Delete_Test()
{
HttpClient httpClient = new HttpClient()
{
BaseAddress = new Uri(TestConfig.WebApiBaseUrl),
};
var para_id = 2;
//发POST请求(URL传参)
var responseMessage = await httpClient.DeleteAsync($"/api/Normal/Delete?Id={para_id}");
//确保响应正常
responseMessage.EnsureSuccessStatusCode();
Assert.NotNull(responseMessage);
Assert.True(responseMessage.IsSuccessStatusCode);
var result = await responseMessage.Content.ReadFromJsonAsync<BaseResult<int>>();
Assert.IsType<BaseResult<int>>(result);
Assert.Equal(1, result.Code);
Assert.Equal(para_id, result.Data);
}
[Fact]
public async Task Delete2_Test()
{
HttpClient httpClient = new HttpClient()
{
BaseAddress = new Uri(TestConfig.WebApiBaseUrl),
};
//Delete 默认不使用请求体如果使用的话需要Content配合 RequestMessage
var account = new Account() { Id = 2, Name = "小明", Password = "123456", Role = "Admin" };
var requestMessage = new HttpRequestMessage(HttpMethod.Delete, "/api/Normal/DeleteForJsonData");
//requestMessage.Content = JsonContent.Create(account);
//也可以下面的,极少有使用(可自定义JsonSerializerOptions)
//requestMessage.Content = JsonContent.Create(account,JsonTypeInfo.CreateJsonTypeInfo<Account>( JsonSerializerOptions.Default),new System.Net.Http.Headers.MediaTypeHeaderValue("application/json","utf-8"));
//发POST请求(URL传参)
var responseMessage = await httpClient.SendAsync(requestMessage);
//确保响应正常
responseMessage.EnsureSuccessStatusCode();
Assert.NotNull(responseMessage);
Assert.True(responseMessage.IsSuccessStatusCode);
var result = await responseMessage.Content.ReadFromJsonAsync<BaseResult<Account>>();
Assert.IsType<BaseResult<Account>>(result);
Assert.Equal(1, result.Code);
}
#endregion
#region OPTIONS 请求
[Fact]
public async Task OPTIONS_Test()
{
HttpClient httpClient = new HttpClient()
{
BaseAddress = new Uri(TestConfig.WebApiBaseUrl),
};
var requestMessage = new HttpRequestMessage(HttpMethod.Options, "/api/Normal/OptionsSimple");
//响应
var responseMessage = await httpClient.SendAsync(requestMessage);
//响应正常
Assert.True(responseMessage.IsSuccessStatusCode);
Assert.NotNull(responseMessage);
var result = await responseMessage.Content.ReadFromJsonAsync<BaseResult<string>>();
Assert.IsType<BaseResult<string>>(result);
Assert.Equal(1, result?.Code);
}
#endregion
#region PATCH 请求
#endregion
#region TRACE 请求
#endregion
#region CONNECT 请求
#endregion
}
}