如何模拟将方法设置为 return 不同的值

How to mock setup a method to return different value

下面是我正在尝试为 CallMethod 编写单元测试用例的代码

public async Task<String> CallMethod(string accountName)
        {
            var response= await GetResponseAsync(Name);

            var finalresponse= await PostReponseAsync(response);

            return finalresponse;
        }
private async Task GetResponseAsync(string Name)
        {
            var param = Name;
            using (var httpClient = _httpClientFactory.CreateClient())
            {

                httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "token");
                var response = await httpClient.GetAsync(URL +"?" + param);
                if (response != null)
                {
                    var responseMessage = await response.Content.ReadAsStringAsync();
                }
            }
        }
private async Task PostReponseAsync(string reponse)
        {
            var json = JsonConvert.SerializeObject(reponse);
            var data = new StringContent(json, Encoding.UTF8, "application/json");

            using (var httpClient = _httpClientFactory.CreateClient())
            {
                httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "token");
                var response = await httpClient.PostAsync(URl, data);
                if (response != null)
                {
                    var responseMessage = await response.Content.ReadAsStringAsync();
                }
            }
        }

单元测试方法:

[TestMethod]
        public async Task CallMethod()
        {
            // Arrange
            string Name = "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);

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

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

            // Assert            
        }

对于 GetResponseAsync 方法,我正在获取响应,但是当调用 PostReponseAsync 方法时,它抛出异常,如下所示

Project.CallMethod threw exception: System.ObjectDisposedException: Cannot access a disposed object. Object name: 'System.Net.Http.HttpClient

谁能帮我解决这个问题。

从工厂模拟单独的客户端,因为每个方法都会处理它使用的客户端。

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

    var postResponseMessage = new HttpResponseMessage {
        StatusCode = HttpStatusCode.OK,
        Content = new StringContent("Message2"),
    };
    var postHandlerMock = new Mock<HttpMessageHandler>();
    postHandlerMock.Protected()
        .Setup<Task<HttpResponseMessage>>("SendAsync", ItExpr.IsAny<HttpRequestMessage>(), ItExpr.IsAny<CancellationToken>())
        .ReturnsAsync(postResponseMessage);

    var getHttpClient = new HttpClient(getHandlerMock.Object);
    var postHttpClient = new HttpClient(postHandlerMock.Object);

    _mockHttpClientFactory
        .SetupSequence(_ => _.CreateClient(It.IsAny<string>()))
        .Returns(getHttpClient)
        .Returns(postHttpClient);

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

    // Assert
    //...      
}