提问人:Soheil 提问时间:11/8/2023 最后编辑:Soheil 更新时间:11/9/2023 访问量:72
处理程序未在 xunit 中返回响应消息
Handler did not return a response message in xunit
问:
我正在使用最小起订量包为我的服务编写单元测试。
我正在嘲笑嘲笑,但我收到了这个欠时错误消息HttpMessageHandler
HttpClient
System.InvalidOperationException:处理程序未返回响应 消息。
这是我的服务方法
public async Task<PaymentDataResponse> PaymentRequest(double amount, string mobileNo)
{
var client = GetClient(mobileNo);
var request = new PaymentRequest()
{
Amount = amount,
CellNumber = SuitablePhoneNumber(mobileNo),
TerminalId = _paymentInfoSetting.TerminalId,
RedirectUrl = _paymentInfoSetting.RedirectUrl
};
var response = await client.PostAsJsonAsync(_paymentInfoSetting.TokenPath, request, new System.Text.Json.JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase });
if (!response.IsSuccessStatusCode)
{
throw new PaymentException();
}
var responseModel = await response.Content.ReadFromJsonAsync<PaymentResponse>();
return responseModel.Data;
}
private HttpClient GetClient(string phoneNumber)
{
var client = _httpClientFactory.CreateClient();
client.BaseAddress = new Uri(_paymentInfoSetting.BaseUrl);
client.DefaultRequestHeaders.Add("apiKey", _paymentInfoSetting.ApiKey);
client.DefaultRequestHeaders.Add("mobile", phoneNumber);
return client;
}
这是我的单元测试:
[Fact]
public async Task PaymentRequest_ShouldReturnCorrectData()
{
// Arrange
var amount = _fixture.Create<double>();
var mobileNo = _paymentInfoSetting.PhoneNumber;
var paymentRequest = _fixture.Build<PaymentRequest>()
.With(q => q.Amount, amount).With(q => q.TerminalId, _paymentInfoSetting.TerminalId).With(q => q.RedirectUrl, _paymentInfoSetting.RedirectUrl)
.With(q => q.CellNumber, mobileNo)
.Create();
var paymentDataResponse = _fixture.Create<PaymentDataResponse>();
var paymentResponse = _fixture.Build<PaymentResponse>().With(q => q.Data, paymentDataResponse).Create();
var response = new HttpResponseMessage(HttpStatusCode.OK);
// response.Content = new StringContent(JsonConvert.SerializeObject(paymentResponse), Encoding.UTF8, "application/json");
response.Content = JsonContent.Create(paymentRequest, options: new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase });
var handler = new Mock<HttpMessageHandler>();
// config 1
//handler.Protected()
// .Setup<Task<HttpResponseMessage>>("SendAsync", ItExpr.IsAny<HttpRequestMessage>(), ItExpr.IsAny<CancellationToken>())
// .ReturnsAsync(response);
// config 2
//handler.Protected()
// .Setup<Task<HttpResponseMessage>>("SendAsync", ItExpr.Is<HttpRequestMessage>(req =>
// req.Content.ReadAsStringAsync().Result == JsonConvert.SerializeObject(paymentRequest)), ItExpr.IsAny<CancellationToken>())
// .ReturnsAsync(response);
// config 3
handler.Protected()
.Setup<Task<HttpResponseMessage>>("SendAsync", ItExpr.Is<HttpRequestMessage>(req =>
req.Content == JsonContent.Create(paymentRequest, null, new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase })
), ItExpr.IsAny<CancellationToken>())
.ReturnsAsync(response);
var httpClient = new HttpClient(handler.Object);
_httpClientFactoryMock.Setup(q => q.CreateClient(It.IsAny<string>())).Returns(httpClient);
// Act
var result = await _service.PaymentRequest(amount, mobileNo);
var resultJson = JsonConvert.SerializeObject(result);
var paymentDataResponseJson = JsonConvert.SerializeObject(paymentDataResponse);
// Assert
_httpClientFactoryMock.Verify(q => q.CreateClient(It.IsAny<string>()), Times.Once);
resultJson.ShouldBe(paymentDataResponseJson);
}
配置 1 正在工作,但我想设置特定请求,所以我正在尝试配置 2,3,但我收到错误。
答:
0赞
Soheil
11/9/2023
#1
我用嘲笑来修复它HttpRequestMessage
var httpRequestMessage = _fixture.Build<HttpRequestMessage>().With(q => q.Content, JsonContent.Create(paymentRequest, It.IsAny<MediaTypeHeaderValue>(), It.IsAny<JsonSerializerOptions>())).Create();
var handler = new Mock<HttpMessageHandler>();
handler.Protected()
.Setup<Task<HttpResponseMessage>>("SendAsync", ItExpr.Is<HttpRequestMessage>(req =>
req.Content.ReadAsStringAsync().Result == httpRequestMessage.Content.ReadAsStringAsync().Result), ItExpr.IsAny<CancellationToken>())
.ReturnsAsync(httpResponseMessage);
评论
SendAsync
req.Content
PaymentRequest
paymentRequest
PaymentRequest
record
class