我有一點完美的風暴阻止了我測試課程。該課程是RestClient
,它包裝了內部的HttpClient
(我不能修改)。 HttpClient
上的ExecuteMethod
方法無效。它接受IHttpMethod
,並根據來自服務器的響應修改此對象。我想嘲笑ExecuteMethod
,以便它爲我修改IHttpMethod
。我正在嘗試使用Callback
來實現此目的,但它不起作用。使用Moq將參數修改爲虛擬無效方法
這裏的發送請求的代碼:
var httpClient = this.httpClientFactory.CreateHttpClient();
httpClient.ExecuteMethod(method);
var response = this.GetResourceResponse<T>(method.ResponseBodyAsStream.AsString());
response.ResponseHeaders = method.ResponseHeaders;
response.Status = method.StatusCode.ToString();
response.StatusCode = (int)method.StatusCode;
return response;
這是我的企圖在嘲諷:
var mockHttpMethod = new Mock<IHttpMethod>();
mockHttpMethod.Setup(m => m.ResponseBodyAsStream).Returns(new MemoryStream(Encoding.UTF8.GetBytes("foo")));
var modifyHttpMethod = new Action<IHttpMethod>(m =>
{
m = mockHttpMethod.Object;
});
var mockHttpClient = new Mock<IHttpClient>();
mockHttpClient.Setup(c => c.ExecuteMethod(It.IsAny<IHttpMethod>()))
.Callback<IHttpMethod>(modifyHttpMethod);
var mockHttpClientFactory = new Mock<ILegalHoldHttpClientFactory>();
mockHttpClientFactory.Setup(f => f.CreateHttpClient()).Returns(mockHttpClient.Object);
var restClient = new RestClient(mockHttpClientFactory.Object);
當執行modifyHttpMethod
行動,我看到兩件事情,這兩者我期待:
- 傳入
IHttpMethod
(m
)有p我期望它具有的性能。 - 將模擬對象分配給
m
後,它包含我在測試中設置的殘段值。
然而,在執行後回調,並控制返回到我的應用程序的代碼,我method
變量仍然有我在上面的步驟1,嘗試讀取method.ResponseBodyAsStream
時導致空引用異常看到了它的舊值。
我試圖做什麼甚至可以實現?如果是這樣,怎麼樣?謝謝!
我不認爲問題是與擴展方法。我可以看到擴展方法如何讀取流並關閉它,使其不可用,但在AsString()方法執行之前流實際上不可用。我不知道爲什麼你的代碼可以工作,而我不知道。我最終做了一些重構,使其更具可測性,所以這不再是一個問題,但我仍然希望它能夠工作,因爲它看起來像一種有用的技術。非常感謝您的回覆。 – Samo 2012-02-15 17:27:33
沒問題 - 如果你有一個更可測試的方法,那總是很好。 :)但是,我會拿走的是,我敢肯定,你可以以某種方式或另一種方式完成Moq想要的東西。有時到達那裏並不容易,但它非常靈活。 – 2012-02-15 17:34:35