我会将我的答案分成两部分;第一部分是您正在寻找的解决方案......第二部分我将讨论您在UT环境中的其他选项(因此,此答案将有助于其他人...)
既然你已经使用MsFakes,您可以使用Shims创建一个实例。 以下片段是其示出了一个实例的方式来初始化和使用ShimHttpWebResponse
:
[Test]
public async Task InitializeShimHttpWebResponse()
{
using (ShimsContext.Create())
{
ShimWebRequest.AllInstances.GetResponseAsync = (x) =>
{
/* you can replace the var with WebResponse if you aren't going to set any behavior */
var res = new ShimHttpWebResponse();
return Task.FromResult((WebResponse)res);
};
ShimWebRequest.CreateString = uri =>
{
WebRequest req = new ShimFileWebRequest();
return req;
};
var request = WebRequest.Create("");
var response = await request.GetResponseAsync() as HttpWebResponse;
Assert.IsNotNull(response);
}
}
伪造品配置:
<Fakes xmlns="http://schemas.microsoft.com/fakes/2011/">
<Assembly Name="System" Version="4.0.0.0"/>
<ShimGeneration>
<Add FullName="System.Net.HttpWebResponse"/>
<Add FullName="System.Net.WebRequest"/>
<Add FullName="System.Net.HttpWebRequest"/>
<Add FullName="System.Net.FileWebRequest"/>
</ShimGeneration>
</Fakes>
只是为了总结本节;国际海事组织,对于一般情况下,使用代码编织工具(MsFakes)是正确的方式来处理这种情况(我在下一节中更详细地解释)
正如我看到你有4个选项来创建一个新的实例的HttpWebResponse
:
使用反射 - 在这种情况下,一个坏主意(UT ..)
2.传承 - 自定义的模拟...
使用代理b有框架Eg; Moq,Rhinomocks等
4.使用代码编织工具(就像您已经使用过的那样)。 Msfakes,Typemock Isolator等。
还有一个选择:创建一个集成测试,而不是UT ...
1.反思:
HttpWebResponse
有3个C'tors;(public,internal,protected)
要使用内部\公共C'tors,您将不得不使用反射,但是在大多数情况下,它不会开箱即用,然后您将不得不违反一些UT规则(小型,快速等) ...)
2例,其中反射会开箱的是:
你不调用实例任何有问题的属性/方法和SUT(被测的人)通过这个实例来一个他的依赖关系
您将使用更多反射初始化实例字段。
虽然第一个是一个简单的例子(如果这是你的情况,那么你应该使用反射)第二个是UT的背景下不好的做法;你的UTs不会很小/可读/可维护,执行时间会增加,微软可能会做一些重构,这可能会破坏你的UTs。
对于受保护的应该通过继承来调用它(compile vs. runtime ...)。
2.继承:
的保护C'tor也有过时的属性,但属性IsError设置为false,这可以让你继承这个类,然后你就可以改变方法/属性的行为;虚拟覆盖,非虚拟 - 仅当您访问类成员(或反射)
此选项的主要缺点是您必须生成的代码数量及其复杂性。
3.使用基于代理框架:
现场这些工具使用反射来创建基于类的继承的实例背后(合并选项1和2) 这些工具有一些内置的方法,使你的假代码更小/可读/可维护。
缺点:(我不会指出的基于代理的工具,所有的缺点...)
你仍然无法改变的非虚拟方法的行为。
您没有访问实例成员。
这2个可以通过使用代码编织工具来解决。
4。代码编织工具:
这些工具可以让你做几乎任何事情,这就是为什么这些工具对于一般情况最好的原因(我可以总结句子的主要缺点 - 强大的功能带来巨大的责任.. )。 就你而言,它们为您提供最佳解决方案; 既然HttpWebResponse
有一个非虚拟方法,你不想重构你的代码,这对你来说是正确的解决方案。
但是Msfakes并没有为UT提供额外的方法/功能(AssertsWasCalled
,counting等等),所以除非你打算用其他工具替换这个工具,你应该把它和代理基础工具(免费工具!!!!)