【问题标题】:Unit Test using MS fakes: HttpClient and await使用 MS fakes 进行单元测试:HttpClient 和 await
【发布时间】: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 中的。这就像询问如何对intstring 进行单元测试。您是否在问如何 mock 它们,以便您可以测试 MyClassGetYourClass
  • 如何测试这些方法
  • 不要。你不需要。如果 URL 错误或服务器返回响应,您已经知道他们会做什么。需要测试的是您的代码,而不是.NET。如果要模拟 HttpClient,请将自己的 HttpMessageHandler 传递给构造函数
  • 此外,您发布的代码试图mock 类,而不是测试它们。如果您在 MyClass 构造函数中注入一个 HttpMessageHandler 会容易得多,如果没有指定则使用默认值。 Check the source.
  • @user2323308 您的类与实现问题紧密耦合。考虑审查您的设计选择并重构您的类,使其依赖于抽象而不是具体化,这使得孤立地测试被测主题变得困难。

标签: c# unit-testing httpclient shim


【解决方案1】:

声明您的测试以异步方式运行并等待源类的响应

[TestMethod]
public async Task TestMethod1()
{
    using (ShimsContext.Create())
    {
        MyClass obj = new MyClass();
        ShimHttpClient shimHttpClient = new ShimHttpClient();
        ShimHttpClient.Constructor = (t) =>
        {
            shimHttpClient = new ShimHttpClient();
            await shimHttpClient.GetAsyncString = (a) =>
            {
                return new System.Threading.Tasks.Task<System.Net.Http.HttpResponseMessage>(function1);
            };
        };
        var returnVal = await obj.GetYourClass();
        Assert.IsNotNull(returnVal);
        //make more assertations on the returnVal 
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-06
    • 2017-03-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多