Como faço para zombar do HttpContext no 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). ... } 

meu controlador base tem um overrride do Initialize que obtém este requestContext. Estou tentando passar isso, mas não estou fazendo algo certo.

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

Onde posso obter mais informações sobre como zombar de meu RequestContext e HttpContext usando o Moq? Eu estou tentando zombar de cookies e do contexto geral.

HttpContext é somente leitura, mas na verdade é derivado do ControllerContext, que você pode definir.

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

Crie uma solicitação, uma resposta e coloque-as em HttpContext:

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

Obrigado usuário 0100110010101.

Funcionou para mim e aqui eu tive um problema ao escrever o testcase para o código abaixo:

  var currentUrl = Request.Url.AbsoluteUri; 

E aqui estão as linhas que resolveram o 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); 

Pode ser útil para os outros.

Aqui está um exemplo de como você pode configurar isso: Mocking HttpContext HttpRequest e HttpResponse para UnitTests (usando o Moq)

Observe os methods de extensão que realmente ajudam a simplificar o uso dessas classs de simulação:

 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(); 

Aqui está um exemplo de como escrever um teste de unidade usando moq para verificar se um HttpModule está funcionando como esperado: Teste de unidade para HttpModule usando Moq para envolver HttpRequest

Atualização: esta API foi refatorada para

  • HttpContextFactory.cs
  • esses vários arquivos de methods de extensão Http *

Aqui está como eu usei o ControllerContext para passar um caminho de aplicativo falso:

 [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."); } }