模拟HttpWebResponse /应答器与WebRequest.Register preFIX [英] Mock HttpWebResponse/responder with WebRequest.RegisterPrefix

查看:204
本文介绍了模拟HttpWebResponse /应答器与WebRequest.Register preFIX的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一些code我试图单元测试,并从我可以告诉,这是根本不可能的。有几个问题与此类似,其中的一些错误声称要解决这个问题,但是没有人可以实际测试我的产品code。下面是重要的行的样品;

 的WebRequest REQ =(WebRequest的)WebRequest.Create(URL);
            WebResponse类RESP =(WebResponse类)req.GetResponse();
            / * HttpWebResponse HTT preSP =(HttpWebResponse)RESP;

            如果(HTT presp.Status code!=(的HTTPStatus code)200)
            {
                _log.Error(的String.Format(:收到非200状态:{0},HTT presp.Status code));
                返回默认(T); //默认(T)== NULL所有引用类型
            } * /
 

在上面的code,注释掉块是实际上应该是在我的产品。这两条线上面,我不得不使用它的订货量大,使其可以进行单元测试。

我模拟的单元测试是基于我的例子<一href="http://blog.salamandersoft.co.uk/index.php/2009/10/how-to-mock-httpwebrequest-when-unit-testing/"相对=nofollow>此处它说,它嘲笑 HttpWebResponse 但实际上嘲笑 WebResponse类。从我可以告诉它不可能嘲笑 HttpWebResponse ,因为它的构造均出现了德precated ......这里有一个例子修改从code该博客发布;

 类TestWebReponse:HttpWebResponse
{
    流responseStream;

    ///&LT;总结&gt;的初始化℃的新实例;看到CREF =TestWebReponse/&GT;
    ///与响应流中返回&lt; /总结&gt;
    公共TestWebReponse(流responseStream)
    {
        this.responseStream = responseStream;
    }

    ///&LT;总结&gt;见&LT;见CREF =WebResponse.GetResponseStream/&GT;&LT; /总结&gt;
    公共覆盖流GetResponseStream()
    {
        返回responseStream;
    }
}
 

不过上面不会因编译 HttpWebResponse没有一个构造函数0参数错误。有没有人有一个工作围绕这个,它采用了类似的机制,拦截产品的codeS请求,但能够返回的 HttpWebResponse ?惩戒 WebResponse类刚才根本就没有为这些类型的应用程序非常有用(没有休息的消费者应该使用的WebRequest / WebResponse类赞成的HttpWebRequest / HttpWebResponse ),这是点我必须测试所以用起订量或类似的工具,使我的方法之一返回对象是不是一种选择,因为它只是绕过code我想测试(这是明确的是二事情是我的请求有效,我们正确地反序列化响应)。所以答案,唯一的限制是,测试code需要保持与此类似;

 字符串响应= JsonConvert.SerializeObject(预期);
WebRequest.Register preFIX(测试,新TestWebRequestCreate());
TestWebRequest请求= TestWebRequestCreate.CreateTestRequest(响应);

VAR的客户=新FakeProprietaryHTTPClient();
PropietaryDataType解析度= client.MakeRequestThatReturnsDeserializedPropietaryDataType();
//做断言针对该PropertaryDataType
 

解决方案

要模拟TestWebRequest,TestWebResponse班组长,我将使用概念,叫做PartialMock。

使用PartialMock您可以创建的WebRequest,WebResponse类的实例,然后覆盖一些方法。(我们通常使用抽象类这种方法)

 类TestWebRequestCreate:IWebRequestCreate
    {

        静态的WebRequest _nextRequest;
        静态只读对象LockObject =新的对象();

        静态公网的WebRequest NextRequest
        {
            {返回_nextRequest; }
            组
            {
                锁定(LockObject)
                {
                    _nextRequest =价值;
                }
            }
        }

        公共WebRequest的创建(URI URI)
        {
            返回_nextRequest;
        }

        公共静态的WebRequest CreateTestRequest(字符串响应)
        {

            VAR请求= MockRepository.GeneratePartialMock&LT; WebRequest的&GT;();

            CreateTestWebRequest(请求,响应);

            NextRequest =请求;

            返回请求;
        }

        私有静态无效CreateTestWebRequest(WebRequest的要求,串responseStr)
        {
            VAR requestStream =新的MemoryStream();
            request.Stub(X =&GT; x.GetRequestStream())。返回(requestStream);
            request.Stub(X =&GT; x.Method).PropertyBehavior();
            request.Stub(X =&GT; x.ContentType).PropertyBehavior();
            request.Stub(X =&GT; x.ContentLength).PropertyBehavior();

            VAR响应= CreateTestWebResponse(responseStr);
            request.Stub(X =&GT; x.GetResponse())返回(响应)。

        }

        私有静态WebResponse类CreateTestWebResponse(字符串responseStr)
        {
            变种响应= MockRepository.GeneratePartialMock&其中; HttpWebResponse&GT;();
            VAR responseStream =新的MemoryStream(System.Text.Encoding.UTF8.GetBytes(responseStr));
            response.Stub(X =&GT; x.GetResponseStream())返回(responseStream)。

            返回响应;
        }
    }
 

现在测试的所有类在一起:

  VAR响应=我在这里的响应字符串;
        WebRequest.Register preFIX(测试,新TestWebRequestCreate());
        变种请求= TestWebRequestCreate.CreateTestRequest(响应);

        VAR URL =测试:// MyUrl;

        变种F = WebRequest.Create(URL);

        VAR的反响= f.GetResponse()作为HttpWebResponse;

        VAR流= responce.GetResponseStream();

        VAR内容=新的StreamReader(流).ReadLine();

        Assert.AreEqual(回应,内容);
 

这个概念我模拟您的链接继承。

编辑:

我用犀牛嘲笑 - 在我的例子部分模拟

是一个链接到我的解决方案。

I have some code I'm trying to unit test and from what I can tell, it's simply not possible. There are several questions similar to this, some of which incorrectly claim to solve this problem however none them can actually test my product code. Below is a sample of the important lines;

            WebRequest req = (WebRequest)WebRequest.Create(url);
            WebResponse resp = (WebResponse)req.GetResponse();
            /*HttpWebResponse httpResp = (HttpWebResponse)resp;

            if (httpResp.StatusCode != (HttpStatusCode)200)
            {
                _log.Error(String.Format("Recieved non-200 status: {0}", httpResp.StatusCode));
                return default(T); // default(T) == null for all reference types
            }*/

In the above code, the commented out block is what should actually be in my product. The two lines above it I've had to use in it's palce to make it unit testable.

My mock for unit testing is based my the example here which says it mocks HttpWebResponse but in fact mocks WebResponse. From what I can tell it's not possible to mock the HttpWebResponse because it's constructors have both been deprecated... Here is an example modifying the code from that blog posting;

class TestWebReponse : HttpWebResponse
{
    Stream responseStream;

    /// <summary>Initializes a new instance of <see cref="TestWebReponse"/>
    /// with the response stream to return.</summary>
    public TestWebReponse(Stream responseStream)
    {
        this.responseStream = responseStream;
    }

    /// <summary>See <see cref="WebResponse.GetResponseStream"/>.</summary>
    public override Stream GetResponseStream()
    {
        return responseStream;
    }
}

However the above will not compile due to the HttpWebResponse does not have a constructor that takes 0 arguments error. Does anyone have a work around for this that employs a similar mechanism for intercepting the product codes request but is capable of returning an HttpWebResponse? Mocking WebResponse just simply isn't very useful for these types of applications (no rest consumer should be using WebRequest/WebResponse in favor of HttpWebRequest/HttpWebResponse) and this is the point at which I must test so using Moq or a similar utility to make one of my methods return the object is not an option, as it would just circumvent the code I'm trying to test (which to be clear is two things; is my request valid and do we correctly deserialize the response). So the only restriction for answers is that the test code needs to remain similar to this;

string response = JsonConvert.SerializeObject(expected);
WebRequest.RegisterPrefix("test", new TestWebRequestCreate());
TestWebRequest request = TestWebRequestCreate.CreateTestRequest(response);

var client = new FakeProprietaryHTTPClient();
PropietaryDataType res = client.MakeRequestThatReturnsDeserializedPropietaryDataType();
// do asserts against that PropertaryDataType

解决方案

To simulate TestWebRequest, TestWebResponse classs, i'm going to use concept called PartialMock.

With PartialMock you can create an instance from WebRequest, WebResponse and then override some methods.(we usually apply this approach on abstract classes)

    class TestWebRequestCreate : IWebRequestCreate
    {

        static WebRequest _nextRequest;
        static readonly object LockObject = new object();

        static public WebRequest NextRequest
        {
            get { return _nextRequest; }
            set
            {
                lock (LockObject)
                {
                    _nextRequest = value;
                }
            }
        }

        public WebRequest Create(Uri uri)
        {
            return _nextRequest;
        }

        public static WebRequest CreateTestRequest(string response)
        {

            var request = MockRepository.GeneratePartialMock<WebRequest>();

            CreateTestWebRequest(request, response);

            NextRequest = request;

            return request;
        }

        private static void CreateTestWebRequest(WebRequest request, string responseStr)
        {
            var requestStream = new MemoryStream();
            request.Stub(x => x.GetRequestStream()).Return(requestStream);
            request.Stub(x => x.Method).PropertyBehavior();
            request.Stub(x => x.ContentType).PropertyBehavior();
            request.Stub(x => x.ContentLength).PropertyBehavior();

            var response = CreateTestWebResponse(responseStr);
            request.Stub(x => x.GetResponse()).Return(response);

        }

        private static WebResponse CreateTestWebResponse(string responseStr)
        {
            var response = MockRepository.GeneratePartialMock<HttpWebResponse>();
            var responseStream = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(responseStr));
            response.Stub(x => x.GetResponseStream()).Return(responseStream);

            return response;
        }
    }

now test all classes together:

        var response = "my response string here";
        WebRequest.RegisterPrefix("test", new TestWebRequestCreate());
        var request = TestWebRequestCreate.CreateTestRequest(response);

        var url = "test://MyUrl";

        var f = WebRequest.Create(url);

        var responce = f.GetResponse() as HttpWebResponse;

        var stream = responce.GetResponseStream();

        var content = new StreamReader(stream).ReadLine();

        Assert.AreEqual(response, content);

with this concept i simulate the inheritance in your link.

Edit:

I used rhino mocks - partial mock in my example.

This is a link to my solution.

这篇关于模拟HttpWebResponse /应答器与WebRequest.Register preFIX的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆