提问人:John Saunders 提问时间:1/9/2014 最后编辑:CommunityJohn Saunders 更新时间:6/7/2015 访问量:595
如何对依赖于 HttpWebRequest 和 HttpWebResponse 的现有代码进行单元测试?
How to Unit Test Existing Code that Relies on HttpWebRequest and HttpWebResponse?
问:
我已经看到了以下问题:
这些对我没有帮助,因为我需要:
- 测试直接使用 / 且不带接口的现有代码
WebRequest
WebResponse
- 现有代码依赖于 / ,所以我不能使用自己的派生和类。
HttpWebRequest
HttpWebResponse
WebRequest
WebResponse
我知道 ,并且有一个成功的单元测试,证明它有效(一旦你得到正确的前缀)。但该测试只是测试和 .WebRequest.RegisterPrefix
WebRequest
WebResponse
我尝试了以下方法,但它给出了编译错误(不是警告):
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,实际上有一点时间限制。该项目几乎已经完成,因此购买的新模拟框架是不可能的。
答:
在模拟像 httpcontext 这样的单例时,我通常更喜欢使用像 MOQ 这样的模拟框架 asp.net。
还有其他用于模拟的框架,但我发现最小起订量非常灵活和直观
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
评论
HttpContextBase
HttpWebRequest
HttpWebRequestBase
HttpWebRequest
HttpWebResponse
test://localhost/
http://localhost/DUMMY_SERVICE
HttpListener
我只是遇到了同样的问题。坦率地说,Microsoft 设置它的方式没有多大意义 - 在 WebRequest.Create 中,它们有一个抽象工厂,但它们既没有提供我们可以实现的 HttpWebRequest 和 HttpWebResponse 接口,也没有提供我们可以用来继承这些类的受保护构造函数。
我提出的解决方案需要对主程序进行一些小的更改,但它可以工作。基本上,我正在做Microsoft应该做的事情。
- 创建接口 IHttpWebRequest 和 IHttpWebResponse
- 创建实现接口的模拟类
- 为实现接口的 HttpWebRequest 和 HttpWebResponse 创建包装器
- 将对 WebRequest.Create 的调用替换为我自己的工厂方法,该方法根据需要返回包装器或模拟
根据代码的结构,上述操作的实现可能相对简单,或者可能需要在整个项目中进行更改。就我而言,我们所有的 HTTP 请求都通过一个公共服务,所以情况还不错。
无论如何,对于您的项目来说可能为时已晚,但也许这会对其他人有所帮助。
评论