【问题标题】:UWP Windows.Web.HttpClient fake for unit test用于单元测试的 UWP Windows.Web.HttpClient 假冒
【发布时间】:2016-08-14 20:27:07
【问题描述】:

我尝试为 UWP 客户端进行单元测试 REST 通信逻辑。参考the answer for System.Web.HttpClient,发现Windows.Net.HttpClient也接受了一个叫IHttpFilter的说法。

所以,我尝试使用 IHttpFilter 进行自定义响应,但我不知道做出响应的正确方法。

    public class TestFilter : IHttpFilter
    {
        public IAsyncOperationWithProgress<HttpResponseMessage, HttpProgress> SendRequestAsync(HttpRequestMessage request)
        {
            if (request.Method == HttpMethod.Get)
            {
                // response fake response for GET...
            }
        }

        public void Dispose()
        {
            // do nothing
        }
    }           

单元测试的目标方法如下。

    public async Task<string> PostResult(HttpClient httpClient, string username)
    {
        var json = new JsonObject
        {
            {"Username",
                JsonValue.CreateStringValue(string.IsNullOrEmpty(username) ? CommonKey.UnAuthorizedUserPartitionKey : username)
            },
        };

        var content = new HttpStringContent(json.Stringify());
        content.Headers.ContentType = new HttpMediaTypeHeaderValue("application/json");

        // I want to make below line testable...
        var response = await httpClient.PostAsync(new Uri(Common.ProcessUrl), content);
        try
        {
            response.EnsureSuccessStatusCode();
            return null;
        }
        catch (Exception exception)
        {
            return exception.Message ?? "EMPTY ERROR MESSAGE";
        }
    }

请注意,这不是与 System.Web.HttpClient 模拟/伪造相关的重复问题。我要问的是Windows.Web.HttpClient。我没能用它实现

请注意,Windows.Web.Http.IHttpClient内部可访问的,HttpClient 是密封的。很难做 Mock 或继承并覆盖它。

【问题讨论】:

  • 为什么不取消对HttpClient 的整个直接调用,并在抽象背后公开所需的功能。您正在给自己不必要的工作(恕我直言)。
  • 正确。我有点乱 :( 我将目标方法附加到测试。
  • @Nkosi // 不,我想要 Windows.Web.HttpClient 中的IHttpFilter,而不是理论上的基于 System.Web.HttpClient 的模拟/伪造。如果您编写 UWP 代码,它会有些不同,需要进行一些试验。不过我失败了。
  • @Nkosi // 请移除关闭请求。我的问题不是重点。

标签: c# unit-testing win-universal-app


【解决方案1】:

虽然我同意有些人认为有更好的方法来测试 HttpClient 调用,但我将回答您关于如何使用 IHttpFilter 实现创建“假”响应的问题(System.Runtime.InteropServices.WindowsRuntime 是您的朋友)

using System;
using System.Collections.Generic;
using System.Runtime.InteropServices.WindowsRuntime;
using System.Threading;
using System.Threading.Tasks;
using Windows.Foundation;
using Windows.Web.Http;
using Windows.Web.Http.Filters;

namespace Project.UnitTesting
{
    public class FakeResponseFilter : IHttpFilter
    {
        private readonly Dictionary<Uri, HttpResponseMessage> _fakeResponses = new Dictionary<Uri, HttpResponseMessage>();

        public void AddFakeResponse(Uri uri, HttpResponseMessage responseMessage)
        {
            _fakeResponses.Add(uri, responseMessage);
        }

        public void Dispose()
        {
            // Nothing to dispose
        }

        public IAsyncOperationWithProgress<HttpResponseMessage, HttpProgress> SendRequestAsync(HttpRequestMessage request)
        {
            if (_fakeResponses.ContainsKey(request.RequestUri))
            {
                var fakeResponse = _fakeResponses[request.RequestUri];
                return DownloadStringAsync(fakeResponse);
            }

            // Alternatively, you might want to throw here if a request comes 
            // in that is not in the _fakeResponses dictionary.
            return DownloadStringAsync(new HttpResponseMessage(HttpStatusCode.NotFound) { RequestMessage = request });
        }

        private IAsyncOperationWithProgress<HttpResponseMessage, HttpProgress> DownloadStringAsync(HttpResponseMessage message)
        {
            return AsyncInfo.Run(delegate (CancellationToken cancellationToken, IProgress<HttpProgress> progress)
            {
                progress.Report(new HttpProgress());

                try
                {
                    return Task.FromResult(message);
                }
                finally
                {
                    progress.Report(new HttpProgress());
                }

            });
        }
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-12-12
    • 2021-04-09
    • 2019-11-26
    • 2016-02-20
    • 1970-01-01
    • 2012-12-11
    • 2018-06-04
    相关资源
    最近更新 更多