我有一点完美的风暴阻止了我测试课程。该课程是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