如何单元测试依赖于HttpWebRequest和HttpWebResponse的现有代码?

时间:2014-01-09 04:03:59

标签: unit-testing visual-studio-2012 serialization .net-4.5 webrequest

我已经看到了以下问题:

这些对我没有帮助,因为我需要:

  1. 测试直接使用WebRequest / WebResponse但没有接口的现有代码
  2. 现有代码取决于HttpWebRequest / HttpWebResponse,因此我无法使用自己的派生WebRequestWebResponse类。
  3. 我知道WebRequest.RegisterPrefix,并且有一个成功的单元测试证明它有效(一旦你得到正确的前缀)。但该测试只是测试WebRequestWebResponse

    我尝试了以下操作,但它给出了编译错误(不是警告):

    public class MockWebRequest : HttpWebRequest
    {
        public MockWebRequest()
        // : base(new SerializationInfo(typeof (HttpWebRequest), new FormatterConverter()), 
        //        new StreamingContext())
        {
        }
    }
    

    随着两行注释掉,我收到编译错误:

      

    错误CS0619:'System.Net.HttpWebRequest.HttpWebRequest()'已过时:'此API支持.NET Framework基础结构,不能直接在您的代码中使用。'

    当我取消注释这些行时,我收到618警告,但代码在运行时崩溃:

    System.Runtime.Serialization.SerializationException: Member '_HttpRequestHeaders' was not found.
       at System.Runtime.Serialization.SerializationInfo.GetElement(String name, Type& foundType)
       at System.Runtime.Serialization.SerializationInfo.GetValue(String name, Type type)
       at System.Net.HttpWebRequest..ctor(SerializationInfo serializationInfo, StreamingContext streamingContext)
       at UnitTests.MockWebRequest..ctor(String responseJson)
       at UnitTests.MockWebRequestCreator.Create(Uri uri)
       at System.Net.WebRequest.Create(Uri requestUri, Boolean useUriBase)
       at System.Net.WebRequest.Create(Uri requestUri)
       at code under test
    

    我对如何处理这个问题感到茫然(除了默认情况,这只是在这些单元测试中,并且希望代码在测试时得到实现)。

    我可能会“沮丧”并用ISerializable或类似的东西做一些令人讨厌的事情,但这带来了第三个要求:

    3.代码必须是可维护的,并且不能比正在测试的代码复杂得多!

    OBTW,我不能使用TypeMock,实际上有一些时间限制。该项目即将完成,因此一个新的,购买的模拟框架是不可能的。

2 个答案:

答案 0 :(得分:0)

在模拟像httpcontext这样的asp.net单例时,我通常更喜欢使用像MOQ这样的模拟框架。

还有其他框架用于模拟,但我发现MOQ非常灵活和直观

https://github.com/Moq/moq4/wiki/Quickstart

你可以做类似的事情

http://www.syntaxsuccess.com/viewarticle/how-to-mock-httpcontext

另一种方法是通过虚方法抽象调用httpcontext: 与此技术类似: http://unit-testing.net/CurrentArticle/How-To-Remove-Data-Dependencies-In-Unit-Tests.html

答案 1 :(得分:0)

我遇到了同样的问题。坦率地说,微软设置它的方式并没有多大意义 - 在WebRequest.Create中它们有一个抽象工厂,但它们既没有为我们可以实现的HttpWebRequest和HttpWebResponse提供接口,也没有提供受保护的构造函数我们可以用来继承这些类。

我提出的解决方案需要对主程序进行一些小的更改,但它有效。基本上,我正在做微软应该做的事情。

  1. 创建接口IHttpWebRequest和IHttpWebResponse
  2. 创建实现接口的模拟类
  3. 为实现接口的HttpWebRequest和HttpWebResponse创建包装器
  4. 使用我自己的工厂方法替换对WebRequest.Create的调用,该方法根据需要返回包装器或模拟器
  5. 根据代码的结构,上面的实现可能相对简单,或者可能需要在整个项目中进行更改。就我而言,我们所有的HTTP请求都通过一个公共服务,因此它并没有太糟糕。

    无论如何,对你的项目来说可能为时已晚,但也许这将有助于其他人在路上。