2009-09-21 14 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). 
    ... 
} 

Mein Basiscontroller hat einen Override von Initialize, der diesen RequestContext bekommt. Ich versuche das weiterzugeben, aber ich mache nichts richtig.Wie spotze ich den HttpContext in ASP.NET MVC mit Moq?

Wo kann ich weitere Informationen über das Mocking von RequestContext und HttpContext mit Moq erhalten? Ich versuche Cookies und den allgemeinen Kontext zu verspotten.

Antwort

52

HttpContext ist schreibgeschützt, wird aber tatsächlich vom ControllerContext abgeleitet, den Sie festlegen können.

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

Dieser funktionierte für mich, indem er mir erlaubte, einen Schein-HttpContext auf dem Controller zu setzen. –

32

erstellen Anfrage, Antwort und legte sie beide auf Httpcontext:

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

Die Frage ist über die * Base-Klassen, dh HttpRequestBase, nicht HttpRequest - nicht sicher, warum beide selbst benötigt werden und noch ärgerlicher, dass sie "versiegelt" sind. Keine Möglichkeit, LogonUserIdentity zu setzen :( –

+0

Wenn sie meine Referenz gemarshallt werden, ist es immer noch per Remoting möglich, also sollte es kein Problem sein. – 0100110010101

+1

@ChrisKimpton: Als letztes Mittel gibt es immer _reflection_ ;-) – Oliver

5

Hier ist ein Beispiel dafür, wie Sie dies einrichten können: Mocking HttpContext HttpRequest and HttpResponse for UnitTests (using Moq)

Beachten Sie die Erweiterungsmethoden helfen, die wirklich um die Verwendung dieser Spottungsklassen zu vereinfachen:

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

Hier ist ein Beispiel für wie eine Einheit Test mit moq schreiben zu überprüfen, ob ein Httpmodule wie erwartet funktioniert: Unit Test for HttpModule using Moq to wrap HttpRequest

Update: Diese API

3

So habe ich den ControllerContext verwendet, um eine gefälschte Anwendung pat übergeben 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

Warum mussten Sie einen gefälschten Anwendungspfad übergeben? –

+0

Der MVC-Code wird es ausführen und eine Null-Ausnahme auslösen, wenn es nicht dort ist. –

7

Dank Benutzer 0100110010101.

Es ist für mich gearbeitet und hier hatte ich ein Problem während des Testfall für den folgenden Code schreiben:

var currentUrl = Request.Url.AbsoluteUri; 

Und hier sind die Linien, die gelöst das Problem

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

Könnte für die anderen hilfreich sein.

Verwandte Themen