Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

328
Views
No se puede simular HttpClient PostAsync () en pruebas unitarias

Estoy escribiendo casos de prueba usando xUnit y Moq.

Estoy intentando simular PostAsync() de HttpClient, pero aparece un error.

A continuación se muestra el código utilizado para la burla:

 public TestADLS_Operations() { var mockClient = new Mock<HttpClient>(); mockClient.Setup(repo => repo.PostAsync(It.IsAny<string>(), It.IsAny<HttpContent>())).Returns(() => Task.FromResult(new HttpResponseMessage(HttpStatusCode.OK))); this._iADLS_Operations = new ADLS_Operations(mockClient.Object); }

Error:

Expresión no admitida: repo => repo.PostAsync(It.IsAny(), It.IsAny()) Los miembros no reemplazables (aquí: HttpClient.PostAsync) no se pueden usar en expresiones de configuración/verificación.

Captura de pantalla:

ingrese la descripción de la imagen aquí

over 4 years ago · Santiago Trujillo
3 answers
Answer question

0

Los miembros no reemplazables (aquí: HttpClient.PostAsync) no se pueden usar en expresiones de configuración/verificación.

También traté de burlarme de HttpClient de la misma manera que lo hiciste y recibí el mismo mensaje de error.


Solución:

En lugar de burlarse de HttpClient , HttpMessageHandler .

Luego, proporcione el mockHttpMessageHandler.Object a su HttpClient , que luego pasará a su clase de código de producto. Esto funciona porque HttpClient usa HttpMessageHandler bajo el capó:

 // Arrange var mockHttpMessageHandler = new Mock<HttpMessageHandler>(); mockHttpMessageHandler.Protected() .Setup<Task<HttpResponseMessage>>("SendAsync", ItExpr.IsAny<HttpRequestMessage>(), ItExpr.IsAny<CancellationToken>()) .ReturnsAsync(new HttpResponseMessage { StatusCode = HttpStatusCode.OK }); var client = new HttpClient(mockHttpMessageHandler.Object); this._iADLS_Operations = new ADLS_Operations(client);

Nota: También necesitará un

 using Moq.Protected;

en la parte superior de su archivo de prueba.

Luego puede llamar a su método que usa PostAsync desde su prueba, y PostAsync devolverá una respuesta de estado HTTP OK:

 // Act var returnedItem = this._iADLS_Operations.MethodThatUsesPostAsync(/*parameter(s) here*/);

Ventaja: HttpMessageHandler significa que no necesita clases adicionales en su código de producto o su código de prueba.


Recursos útiles:

  1. Pruebas unitarias con HttpClient
  2. Cómo burlarse de HttpClient en sus pruebas unitarias de .NET/C#
over 4 years ago · Santiago Trujillo Report

0

Como explican otras respuestas, debe burlarse de HttpMessageHandler o HttpClientFactory, no de HttpClient. Este es un escenario tan común que alguien creó una biblioteca auxiliar para ambos casos, Moq.Contrib.HttpClient .

Copiando del ejemplo de General Usage para HttpClient :

 // All requests made with HttpClient go through its handler's SendAsync() which we mock var handler = new Mock<HttpMessageHandler>(); var client = handler.CreateClient(); // A simple example that returns 404 for any request handler.SetupAnyRequest() .ReturnsResponse(HttpStatusCode.NotFound); // Match GET requests to an endpoint that returns json (defaults to 200 OK) handler.SetupRequest(HttpMethod.Get, "https://example.com/api/stuff") .ReturnsResponse(JsonConvert.SerializeObject(model), "application/json"); // Setting additional headers on the response using the optional configure action handler.SetupRequest("https://example.com/api/stuff") .ReturnsResponse(bytes, configure: response => { response.Content.Headers.LastModified = new DateTime(2018, 3, 9); }) .Verifiable(); // Naturally we can use Moq methods as well // Verify methods are provided matching the setup helpers handler.VerifyAnyRequest(Times.Exactly(3));

Para HttpClientFactory:

 var handler = new Mock<HttpMessageHandler>(); var factory = handler.CreateClientFactory(); // Named clients can be configured as well (overriding the default) Mock.Get(factory).Setup(x => x.CreateClient("api")) .Returns(() => { var client = handler.CreateClient(); client.BaseAddress = ApiBaseUrl; return client; });
over 4 years ago · Santiago Trujillo Report

0

En lugar de usar directamente una instancia de HttpClient en su código, use una IHttpClientFactory . En sus pruebas, puede crear su propia implementación de IHttpClientFactory que devuelve un HttpClient que se conecta a un TestServer .

Aquí hay un ejemplo de cómo podría verse su Fake Factory:

 public class InMemoryHttpClientFactory: IHttpClientFactory { private readonly TestServer _server; public InMemoryHttpClientFactory(TestServer server) { _server = server; } public HttpClient CreateClient(string name) { return _server.CreateClient(); } }

Luego puede configurar un TestServer en sus pruebas y hacer que su IHttpClientFactory personalizado cree clientes para ese servidor:

 public TestADLS_Operations() { //setup TestServer IWebHostBuilder hostBuilder = new WebHostBuilder() .Configure(app => app.Run( async context => { // set your response headers via the context.Response.Headers property // set your response content like this: byte[] content = Encoding.Unicode.GetBytes("myResponseContent"); await context.Response.Body.WriteAsync(content); })); var testServer = new TestServer(hostBuilder) var factory = new InMemoryHttpClientFactory(testServer); _iADLS_Operations = new ADLS_Operations(factory); [...] }
over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!