【问题标题】:How to mock a OWIN Testserver with RestSharp?如何使用 RestSharp 模拟 OWIN 测试服务器?
【发布时间】:2016-05-20 09:14:35
【问题描述】:

我将 OWIN 与 WebAPI 集成作为 WebApp 使用。未来的计划是使用运行良好的 OWIN 自托管,但 OWIN 测试服务器的实现无法与 RestSharp 一起使用:

没有 RestSharp 的示例:

https://blogs.msdn.microsoft.com/webdev/2013/11/26/unit-testing-owin-applications-using-testserver/

第一次尝试是使用从 RestClient 类派生的模拟类: 公共类 MockRestClient : RestClient { 公共测试服务器测试服务器 { 获取;放; }

    public MockRestClient(TestServer testServer)
    {
        TestServer = testServer;
    }

    public override IRestResponse Execute(IRestRequest request)
    {
        // TODO: Currently the test server is only doing GET requests via RestSharp
        var response = TestServer.HttpClient.GetAsync(request.Resource).Result;
        var restResponse = ConvertToRestResponse(request, response);
        return restResponse;
    }

    private static RestResponse ConvertToRestResponse(IRestRequest request, HttpResponseMessage httpResponse)
    {
        RestResponse restResponse1 = new RestResponse();
        restResponse1.Content = httpResponse.Content.ReadAsStringAsync().Result;
        restResponse1.ContentEncoding = httpResponse.Content.Headers.ContentEncoding.FirstOrDefault();
        restResponse1.ContentLength = (long)httpResponse.Content.Headers.ContentLength;
        restResponse1.ContentType = httpResponse.Content.Headers.ContentType.ToString();
        if (httpResponse.IsSuccessStatusCode == false)
        {
            restResponse1.ErrorException = new HttpRequestException();
            restResponse1.ErrorMessage = httpResponse.Content.ToString();
            restResponse1.ResponseStatus = ResponseStatus.Error;
        }
        restResponse1.RawBytes = httpResponse.Content.ReadAsByteArrayAsync().Result;
        restResponse1.ResponseUri = httpResponse.Headers.Location;
        restResponse1.Server = "http://localhost";
        restResponse1.StatusCode = httpResponse.StatusCode;
        restResponse1.StatusDescription = httpResponse.ReasonPhrase;
        restResponse1.Request = request;
        RestResponse restResponse2 = restResponse1;
        foreach (var httpHeader in httpResponse.Headers)
            restResponse2.Headers.Add(new Parameter()
            {
                Name = httpHeader.Key,
                Value = (object)httpHeader.Value,
                Type = ParameterType.HttpHeader
            });
        //foreach (var httpCookie in httpResponse.Content.)
        //    restResponse2.Cookies.Add(new RestResponseCookie()
        //    {
        //        Comment = httpCookie.Comment,
        //        CommentUri = httpCookie.CommentUri,
        //        Discard = httpCookie.Discard,
        //        Domain = httpCookie.Domain,
        //        Expired = httpCookie.Expired,
        //        Expires = httpCookie.Expires,
        //        HttpOnly = httpCookie.HttpOnly,
        //        Name = httpCookie.Name,
        //        Path = httpCookie.Path,
        //        Port = httpCookie.Port,
        //        Secure = httpCookie.Secure,
        //        TimeStamp = httpCookie.TimeStamp,
        //        Value = httpCookie.Value,
        //        Version = httpCookie.Version
        //    });
        return restResponse2;
    }

不幸的是,我坚持使用 Post 事件,它需要来自 restResponse 的 html 正文。

有没有人做过类似的事情。

顺便说一句:我也可以将 OWIN 单元测试与自托管 OWIN 一起使用,但这不适用于 Teamcity 自动构建。

【问题讨论】:

    标签: c# unit-testing mocking owin restsharp


    【解决方案1】:

    我也将模拟休息客户端更改为使用 Post/Put/Delete 方法。它不是 100% 完成的(缺少身份验证、Cookie、文件等),但在我的情况下就足够了:

    public class MockRestClient : RestClient
    {
        public TestServer TestServer { get; set; }
        public MockRestClient(TestServer testServer)
        {
            TestServer = testServer;
        }
    
        public override IRestResponse Execute(IRestRequest request)
        {
            // TODO: Currently the test server is only doing GET requests via RestSharp
    
            HttpResponseMessage response = null;
    
            Parameter body = request.Parameters.FirstOrDefault(p => p.Type == ParameterType.RequestBody);
            HttpContent content;
    
    
            if (body != null)
            {
                object val = body.Value;
                byte[] requestBodyBytes;
                string requestBody;
    
    
                if (val is byte[])
                {
                    requestBodyBytes = (byte[]) val;
                    content = new ByteArrayContent(requestBodyBytes);
                }
                else
                {
                    requestBody = Convert.ToString(body.Value);
                    content = new StringContent(requestBody);
                }
            }
            else 
                content = new StringContent("");
    
            string urladd = "";
    
            IEnumerable<string> @params = from p in request.Parameters
                where p.Type == ParameterType.GetOrPost && p.Value != null
                select p.Name + "=" + p.Value;
    
            if(!@params.IsNullOrEmpty())
                urladd = "?" + String.Join("&", @params);
    
    
            IEnumerable<HttpHeader> headers = from p in request.Parameters
                                              where p.Type == ParameterType.HttpHeader
                                              select new HttpHeader
                                              {
                                                  Name = p.Name,
                                                  Value = Convert.ToString(p.Value)
                                              };
    
            foreach (HttpHeader header in headers)
            {
                content.Headers.Add(header.Name, header.Value);
            }
    
            content.Headers.ContentType.MediaType = "application/json";
    
            switch (request.Method)
            {
                case Method.GET:
                    response = TestServer.HttpClient.GetAsync(request.Resource + urladd).Result;
                    break;
                case Method.DELETE:
                    response = TestServer.HttpClient.DeleteAsync(request.Resource + urladd).Result;
                    break;
                case Method.POST:
                    response = TestServer.HttpClient.PostAsync(request.Resource + urladd, content).Result;
                    break;
                case Method.PUT:
                    response = TestServer.HttpClient.PutAsync(request.Resource + urladd, content).Result;
                    break;
                default:
                    return null;
            }
    
            var restResponse = ConvertToRestResponse(request, response);
            return restResponse;
        }
    
        private static RestResponse ConvertToRestResponse(IRestRequest request, HttpResponseMessage httpResponse)
        {
            RestResponse restResponse1 = new RestResponse();
            restResponse1.Content = httpResponse.Content.ReadAsStringAsync().Result;
            restResponse1.ContentEncoding = httpResponse.Content.Headers.ContentEncoding.FirstOrDefault();
            restResponse1.ContentLength = (long)httpResponse.Content.Headers.ContentLength;
            restResponse1.ContentType = httpResponse.Content.Headers.ContentType.ToString();
            if (httpResponse.IsSuccessStatusCode == false)
            {
                restResponse1.ErrorException = new HttpRequestException();
                restResponse1.ErrorMessage = httpResponse.Content.ToString();
                restResponse1.ResponseStatus = ResponseStatus.Error;
            }
            restResponse1.RawBytes = httpResponse.Content.ReadAsByteArrayAsync().Result;
            restResponse1.ResponseUri = httpResponse.Headers.Location;
            restResponse1.Server = "http://localhost";
            restResponse1.StatusCode = httpResponse.StatusCode;
            restResponse1.StatusDescription = httpResponse.ReasonPhrase;
            restResponse1.Request = request;
            RestResponse restResponse2 = restResponse1;
            foreach (var httpHeader in httpResponse.Headers)
                restResponse2.Headers.Add(new Parameter()
                {
                    Name = httpHeader.Key,
                    Value = (object)httpHeader.Value,
                    Type = ParameterType.HttpHeader
                });
            //foreach (var httpCookie in httpResponse.Content.)
            //    restResponse2.Cookies.Add(new RestResponseCookie()
            //    {
            //        Comment = httpCookie.Comment,
            //        CommentUri = httpCookie.CommentUri,
            //        Discard = httpCookie.Discard,
            //        Domain = httpCookie.Domain,
            //        Expired = httpCookie.Expired,
            //        Expires = httpCookie.Expires,
            //        HttpOnly = httpCookie.HttpOnly,
            //        Name = httpCookie.Name,
            //        Path = httpCookie.Path,
            //        Port = httpCookie.Port,
            //        Secure = httpCookie.Secure,
            //        TimeStamp = httpCookie.TimeStamp,
            //        Value = httpCookie.Value,
            //        Version = httpCookie.Version
            //    });
            return restResponse2;
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-04-27
      • 2014-06-21
      • 2014-11-21
      • 2021-05-14
      • 2017-03-14
      相关资源
      最近更新 更多