我會將我的答案分成兩部分;第一部分是您正在尋找的解決方案......第二部分我將討論您在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等等),所以除非你打算用其他工具替換這個工具,你應該把它和代理基礎工具(免費工具!!!!)