¿Cómo me burlo del HttpContext en ASP.NET MVC usando Moq?

[TestMethod] public void Home_Message_Display_Unknown_User_when_coockie_does_not_exist() { var context = new Mock(); var request = new Mock(); context .Setup(c => c.Request) .Returns(request.Object); HomeController controller = new HomeController(); controller.HttpContext = context; //Here I am getting an error (read only). ... } 

mi controlador base tiene una sustitución de Initialize que obtiene este requestContext. Estoy tratando de pasar esto pero no estoy haciendo algo bien.

 protected override void Initialize(System.Web.Routing.RequestContext requestContext) { base.Initialize(requestContext); } 

¿Dónde puedo obtener más información sobre cómo burlarse de RequestContext y HttpContext usando Moq? Estoy tratando de burlarme de las cookies y el contexto general.

HttpContext es de solo lectura, pero en realidad se deriva de ControllerContext, que puede establecer.

  controller.ControllerContext = new ControllerContext( context.Object, new RouteData(), controller ); 

Cree una solicitud, respuesta y póngalos a ambos en HttpContext:

 HttpRequest httpRequest = new HttpRequest("", "http://mySomething/", ""); StringWriter stringWriter = new StringWriter(); HttpResponse httpResponse = new HttpResponse(stringWriter); HttpContext httpContextMock = new HttpContext(httpRequest, httpResponse); 

Gracias, usuario 0100110010101.

Me funcionó y aquí tuve un problema al escribir el caso de prueba para el siguiente código:

  var currentUrl = Request.Url.AbsoluteUri; 

Y aquí están las líneas que resolvieron el problema

 HomeController controller = new HomeController(); //Mock Request.Url.AbsoluteUri HttpRequest httpRequest = new HttpRequest("", "http://mySomething", ""); StringWriter stringWriter = new StringWriter(); HttpResponse httpResponse = new HttpResponse(stringWriter); HttpContext httpContextMock = new HttpContext(httpRequest, httpResponse); controller.ControllerContext = new ControllerContext(new HttpContextWrapper(httpContextMock), new RouteData(), controller); 

Puede ser útil para los demás.

Aquí hay un ejemplo de cómo puedes configurar esto: Mocking HttpContext HttpRequest y HttpResponse para UnitTests (usando Moq)

Tenga en cuenta los métodos de extensión que realmente ayudan a simplificar el uso de estas clases de burla:

 var mockHttpContext = new API_Moq_HttpContext(); var httpContext = mockHttpContext.httpContext(); httpContext.request_Write("".line()); httpContext.request_Write(" this is a web page".line()); httpContext.request_Write(""); return httpContext.request_Read(); 

Aquí hay un ejemplo de cómo escribir una prueba unitaria usando moq para verificar que un HttpModule funciona como se esperaba: Prueba unitaria para HttpModule usando Moq para envolver HttpRequest

Actualización: esta API ha sido refactorizada para

  • HttpContextFactory.cs
  • estos archivos múltiples de Http * Extension Methods

Así es como utilicé ControllerContext para pasar una ruta de aplicación falsa:

 [TestClass] public class ClassTest { private Mock mockControllerContext; private HomeController sut; [TestInitialize] public void TestInitialize() { mockControllerContext = new Mock(); sut = new HomeController(); } [TestCleanup] public void TestCleanup() { sut.Dispose(); mockControllerContext = null; } [TestMethod] public void Index_Should_Return_Default_View() { // Expectations mockControllerContext.SetupGet(x => x.HttpContext.Request.ApplicationPath) .Returns("/foo.com"); sut.ControllerContext = mockControllerContext.Object; // Act var failure = sut.Index(); // Assert Assert.IsInstanceOfType(failure, typeof(ViewResult), "Index() did not return expected ViewResult."); } }