2009-09-21 11 views
87
[TestMethod] 
public void Home_Message_Display_Unknown_User_when_coockie_does_not_exist() 
{ 
    var context = new Mock<HttpContextBase>(); 
    var request = new Mock<HttpRequestBase>(); 
    context 
     .Setup(c => c.Request) 
     .Returns(request.Object); 
    HomeController controller = new HomeController(); 

    controller.HttpContext = context; //Here I am getting an error (read only). 
    ... 
} 

il mio controller di base ha un overrride di Initialize che ottiene questa richiestaContext. Sto cercando di passarlo avanti ma non sto facendo qualcosa di giusto.Come si simula HttpContext in ASP.NET MVC usando Moq?

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

Dove posso trovare maggiori informazioni su beffardo mia RequestContext e HttpContext utilizzando Moq? Sto cercando di deridere i biscotti e il contesto generale.

risposta

52

HttpContext è di sola lettura, ma in realtà è derivato da ControllerContext, che è possibile impostare.

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

Questo ha funzionato per me permettendomi di impostare un HttpContext sul controller. –

32

Creare una richiesta, la risposta e li sia messi a HttpContext:

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

La domanda riguarda le * Classi di base, cioè HttpRequestBase, non HttpRequest - non sono sicuro del motivo per cui entrambi sono necessari io stesso e ancor più fastidioso che siano "sigillati". Nessun modo per impostare LogonUserIdentity :( –

+0

Se il mio riferimento è gestito, è ancora possibile tramite remoting, quindi non dovrebbe essere un problema. – 0100110010101

+1

@ChrisKimpton: Come ultima risorsa, c'è sempre _reflection_ ;-) – Oliver

5

Ecco un esempio di come è possibile impostare questa funzione: Mocking HttpContext HttpRequest and HttpResponse for UnitTests (using Moq)

Nota i metodi di estensione che in realtà aiutano per semplificare l'uso di queste classi di derisione:

var mockHttpContext = new API_Moq_HttpContext(); 

var httpContext = mockHttpContext.httpContext(); 

httpContext.request_Write("<html><body>".line()); 
httpContext.request_Write(" this is a web page".line()); 
httpContext.request_Write("</body></html>"); 

return httpContext.request_Read(); 

Ecco un esempio di come scrivere uno unit test utilizzando moq per controllare che un HttpModule funziona come previsto: Unit Test for HttpModule using Moq to wrap HttpRequest

Aggiornamento: questa API è stata riscritta per

3

Ecco come ho usato ControllerContext per passare un falso messaggio di domanda h:

[TestClass] 
public class ClassTest 
{ 
    private Mock<ControllerContext> mockControllerContext; 
    private HomeController sut; 

    [TestInitialize] 
    public void TestInitialize() 
    { 
     mockControllerContext = new Mock<ControllerContext>(); 
     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."); 
    } 
} 
+1

Perché hai bisogno di passare un percorso di applicazione falso? –

+0

Il codice MVC lo eseguirà e genererà un'eccezione null se non è presente. –

7

utente Grazie 0100110010101.

ha funzionato per me e qui ho avuto un problema durante la scrittura del testcase per il codice qui sotto:

var currentUrl = Request.Url.AbsoluteUri; 

Ed ecco le linee che ha risolto il 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); 

Potrebbe essere utile per gli altri.

Problemi correlati