【发布时间】:2018-05-21 08:56:51
【问题描述】:
我有创建 HttpClient 实例并调用一些方法并以异步模式返回响应的类。
对于 ReadAsAsync,我使用了 nuget 包“System.Net.Http.Formatting”。
源代码:
public class MyClass
{
readonly HttpClient client = new HttpClient();
public MyClass()
{
string myUrl = ConfigurationManager.AppSettings["MyWebAPI"];
client.BaseAddress = new Uri(myUrl);
}
public async Task<List<YourClass>> GetYourClass()
{
var filters = "string";
HttpResponseMessage response = await client.GetAsync(filters).ConfigureAwait(false);
if (response.IsSuccessStatusCode)
{
var notes = await response.Content.ReadAsAsync<List<YourClass>>();
return notes;
}
return null;
}
}
public class YourClass
{
private string Address { get; set; }
public YourClass(string address)
{
Address = address;
}
}
单元测试:
[TestClass]
public class UnitTest1
{
[TestMethod]
public void TestMethod1()
{
using (ShimsContext.Create())
{
MyClass obj = new MyClass();
ShimHttpClient shimHttpClient = new ShimHttpClient();
ShimHttpClient.Constructor = (t) =>
{
shimHttpClient = new ShimHttpClient();
shimHttpClient.GetAsyncString = (a) =>
{
return new System.Threading.Tasks.Task<System.Net.Http.HttpResponseMessage>(function1);
};
};
var returnVal = obj.GetYourClass();
}
}
private System.Net.Http.HttpResponseMessage function1()
{
return new System.Net.Http.HttpResponseMessage();
}
}
我们无法更改源代码。但需要通过虚拟调用测试对 GetAsync 和 ReadAsAync 调用进行单元测试。
【问题讨论】:
-
为什么?这些不是您的 类,它们是内置在.NET 中的。这就像询问如何对
int或string进行单元测试。您是否在问如何 mock 它们,以便您可以测试MyClass和GetYourClass? -
如何测试这些方法
-
不要。你不需要。如果 URL 错误或服务器返回响应,您已经知道他们会做什么。需要测试的是您的代码,而不是.NET。如果要模拟 HttpClient,请将自己的 HttpMessageHandler 传递给构造函数
-
此外,您发布的代码试图mock 类,而不是测试它们。如果您在 MyClass 构造函数中注入一个 HttpMessageHandler 会容易得多,如果没有指定则使用默认值。 Check the source.
-
@user2323308 您的类与实现问题紧密耦合。考虑审查您的设计选择并重构您的类,使其依赖于抽象而不是具体化,这使得孤立地测试被测主题变得困难。
标签: c# unit-testing httpclient shim