visual unit test studio net framework asp unit-testing rhino-mocks wcf-web-api

unit testing - unit - Stubbing o burlón ASP.NET Web API HttpClient



unit test web api entity framework (3)

Estoy utilizando los nuevos bits de la API web en un proyecto, y he descubierto que no puedo usar el HttpMessageRequest normal, ya que necesito agregar certificados de cliente a la solicitud. Como resultado, estoy usando el HttpClient (por lo que puedo usar WebRequestHandler ). Todo esto funciona bien, excepto que no es compatible con mechones, por lo menos para Rhino Mocks.

Normalmente crearía un servicio de envoltorio alrededor de HttpClient que usaría en su lugar, pero me gustaría evitarlo si es posible, ya que hay muchos métodos que tendría que envolver. Espero que me haya pasado algo, ¿alguna sugerencia sobre cómo aplastar a HttpClient ?


Como alternativa a las excelentes ideas ya presentadas por @Raj, puede ser posible ir un paso más abajo y simular / falsificar el HttpMessageHandler en HttpMessageHandler lugar.

Si HttpClient una clase que necesita un HttpClient como un parámetro de inyección de dependencia en el constructor, luego, cuando realice la prueba unitaria, puede pasar un HttpClient que ha sido inyectado con su propio HttpMessageHandler . Esta clase simple tiene solo un método abstracto que necesita implementar, de la siguiente manera:

public class FakeHttpMessageHandler : HttpMessageHandler { public HttpRequestMessage RequestMessage { get; private set; } protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { RequestMessage = request; return Task.FromResult(new HttpResponseMessage(HttpStatusCode.OK)); } }

Mi ejemplo trivial simplemente guarda el HttpRequestMessage en una propiedad pública para su posterior inspección y devuelve HTTP 200 (OK), pero puede aumentar esto agregando un constructor que establezca el resultado que desea que se devuelva.

Usarías esta clase así:

public void foo() { //Arrange var fakeHandler = new FakeHttpMessageHandler(); var client = new HttpClient(fakeHandler); var SUT = new ClassUnderTest(client); //Act SUT.DomSomething(); //Assert fakeHandler.RequestMessage.Method.ShouldEqual(HttpMethod.Get); // etc... }

Este enfoque tiene limitaciones, por ejemplo, en un método que realiza múltiples solicitudes o necesita crear múltiples HttpClient ; luego, el controlador falso puede comenzar a ser demasiado complicado. Sin embargo, puede valer la pena considerar para casos simples.


Hace unos meses MockHttp una biblioteca llamada MockHttp que podría ser útil. Utiliza un HttpMessageHandler personalizado con una API fluida (y extensible). Puede inyectar el controlador simulado (o HttpClient) en su clase de servicio y responderá como se configuró.

A continuación se muestra el uso básico. Los métodos When y Respond tienen un montón de sobrecargas, incluida la ejecución de lógica personalizada. La documentación en la página de GitHub entra en muchos más detalles.

var mockHttp = new MockHttpMessageHandler(); // Setup a respond for the user api (including a wildcard in the URL) mockHttp.When("http://localhost/api/user/*") .Respond("application/json", "{''name'' : ''Test McGee''}"); // Respond with JSON // Inject the handler or client into your application code var client = new HttpClient(mockHttp); var response = async client.GetAsync("http://localhost/api/user/1234"); // or without async: var response = client.GetAsync(...).Result; var json = await response.Content.ReadAsStringAsync(); // No network connection required Console.Write(json); // {''name'' : ''Test McGee''}


Utilizo Moq y puedo apagar el HttpClient. Creo que esto es lo mismo para Rhino Mock (no lo he intentado solo). Si solo desea aplazar el HttpClient, el siguiente código debería funcionar:

var stubHttpClient = new Mock<HttpClient>(); ValuesController controller = new ValuesController(stubHttpClient.Object);

Por favor corrígeme si estoy equivocado. Supongo que se está refiriendo a que aquí se está apagando miembros dentro de HttpClient.

Los marcos de objetos de aislamiento / simulacros más populares no le permitirán apagar / configurar en miembros no virtuales. Por ejemplo, el siguiente código lanza una excepción

stubHttpClient.Setup(x => x.BaseAddress).Returns(new Uri("some_uri");

También mencionó que le gustaría evitar crear una envoltura porque envolvería a muchos miembros de HttpClient. No está claro por qué necesita envolver muchos métodos, pero puede envolver fácilmente solo los métodos que necesita.

Por ejemplo :

public interface IHttpClientWrapper { Uri BaseAddress { get; } } public class HttpClientWrapper : IHttpClientWrapper { readonly HttpClient client; public HttpClientWrapper() { client = new HttpClient(); } public Uri BaseAddress { get { return client.BaseAddress; } } }

Las otras opciones que creo que podrían beneficiarte para ti (hay muchos ejemplos por ahí, así que no escribiré el código) Microsoft Moles Framework http://research.microsoft.com/en-us/projects/moles/ Microsoft Fakes: ( si está utilizando VS2012 Ultimate) http://msdn.microsoft.com/en-us/library/hh549175.aspx