You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何Mock设置方法返回不同值?解决单元测试中HttpClient ObjectDisposedException异常

Fixing System.ObjectDisposedException in HttpClientFactory Unit Tests

Let's break down why you're hitting this error and how to fix it quickly:

The Root Cause

Your test creates a single HttpClient instance and tells the mock HttpClientFactory to return that same instance every time CreateClient() is called. But in your production code, both GetResponseAsync and PostReponseAsync wrap their HttpClient usage in a using block.

When the first using block (in GetResponseAsync) finishes, it disposes the shared HttpClient. By the time PostReponseAsync calls CreateClient() again, it gets the already-disposed instance—hence the ObjectDisposedException.

The Fix

Instead of returning the same HttpClient every time, configure the mock HttpClientFactory to return a new HttpClient instance on each CreateClient() call. All these instances will use your pre-configured HttpMessageHandler mock, so your response sequence will still work as expected.

Update your test's Arrange section where you set up the HttpClientFactory:

// Replace this:
// var httpClient = new HttpClient(handlerMock.Object); 
// _mockHttpClientFactory.Setup(_ => _.CreateClient(It.IsAny<string>())).Returns(httpClient); 

// With this:
_mockHttpClientFactory.Setup(_ => _.CreateClient(It.IsAny<string>()))
                      .Returns(() => new HttpClient(handlerMock.Object));

This way, each using block in your production code gets its own fresh HttpClient instance. Since all instances share the same mocked HttpMessageHandler, your SetupSequence will still return GetResponseMessage for the first request and postResponseMessage for the second.

Quick Notes on Your Production Code

I noticed a couple of small typos that might cause issues later:

  • In CallMethod, you're passing Name to GetResponseAsync instead of the method parameter accountName.
  • In PostReponseAsync, you're using URl (lowercase L) instead of URL—this will throw a compilation error if URl isn't defined.

Modified Test Code

Here's the full corrected test method for reference:

[TestMethod] 
public async Task CallMethod_ReturnsFinalResponse() 
{ 
    // Arrange 
    string accountName = "Value"; 
    var GetResponseMessage = new HttpResponseMessage 
    { 
        StatusCode = HttpStatusCode.OK, 
        Content = new StringContent("Message1"), 
    }; 
    var postResponseMessage = new HttpResponseMessage 
    { 
        StatusCode = HttpStatusCode.OK, 
        Content = new StringContent("Message2"), 
    }; 
    var handlerMock = new Mock<HttpMessageHandler>(); 
    handlerMock.Protected().SetupSequence<Task<HttpResponseMessage>>("SendAsync", ItExpr.IsAny<HttpRequestMessage>(), ItExpr.IsAny<CancellationToken>())
        .ReturnsAsync(GetResponseMessage)
        .ReturnsAsync(postResponseMessage); 

    // Updated setup to return new HttpClient each time
    _mockHttpClientFactory.Setup(_ => _.CreateClient(It.IsAny<string>()))
                          .Returns(() => new HttpClient(handlerMock.Object)); 

    // Act 
    var response = await _classUnderTest.CallMethod(accountName); 

    // Assert 
    Assert.AreEqual("Message2", response);
}

内容的提问来源于stack exchange,提问作者Arshit Singh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 19:12:44