如何模拟将方法设置为 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
//...
}
下面是我正在尝试为 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
//...
}