我有一个在同一单元测试中以及在同一类的其他单元测试中多次使用的对象,其定义如下:
private readonly Task<HttpResponseMessage> successfulResponse = Task.FromResult(
new HttpResponseMessage()
{
StatusCode = System.Net.HttpStatusCode.OK,
Content = new StringContent(@"{""EntitySets"":[{""ResultSets"":[{""Results"":[{""Type"":""Message""}],""Total"":2}],""EntityType"":""Message""}]}")
});
然后在每个相关的单元测试中,我都在做这样的事情:
mockHttpClient.Setup(m => m.SendAsync(It.Is<HttpRequestMessage>(v =>
v.RequestUri.Host.Equals("example.com")),
It.IsAny<CancellationToken>())).Returns(successfulResponse);
...其中mockHttpClient
是模拟的HttpClient
。
但是当我进行单元测试时,这种逻辑在要测试的代码内的很多地方执行:
using (HttpResponseMessage response = await this.client.SendAsync(request, cancellationToken))
{
//...
}
...从上方开始,其中this.client
为mockHttpClient
。如您所知,Moq
在此处提供了我预先准备好的successfulResponse
对象,以模拟http响应。
问题是,当执行这样的using
语句的very first执行时,当它离开successfulResponse
块时会处置using
,并且随后的所有using
块都会失败,并且以下例外:
Test method TestProbe_Success threw exception:
System.ObjectDisposedException: Cannot access a disposed object.
Object name: 'System.Net.Http.StringContent'.
所以我的问题是,如何防止被测试的代码处理此对象,该对象在同一单元测试和其他单元测试中多次使用?
将其更改为功能
private readonly Func<Task<HttpResponseMessage>> successfulResponse = () => Task.FromResult(
new HttpResponseMessage() {
StatusCode = System.Net.HttpStatusCode.OK,
Content = new StringContent(@"{""EntitySets"":[{""ResultSets"":[{""Results"":[{""Type"":""Message""}],""Total"":2}],""EntityType"":""Message""}]}")
});
并让设置在其退货中使用委托
mockHttpClient .Setup(m => m.SendAsync(It.Is<HttpRequestMessage>(v => v.RequestUri.Host.Equals("example.com") ), It.IsAny<CancellationToken>()) ) .Returns(successfulResponse());
这样,每次返回响应时,都会使用一个新实例。