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

Mój kontroler bazowy ma overrride Initialize, że get to requestContext. Próbuję to przekazać, ale nie robię czegoś dobrze.Jak wyśmiać HttpContext w ASP.NET MVC za pomocą Moq?

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

Gdzie mogę uzyskać więcej informacji o wyśmiewaniu mojego RequestContext i HttpContext za pomocą Moq? Próbuję wyśmiać ciasteczka i ogólny kontekst.

Odpowiedz

52

HttpContext jest tylko do odczytu, ale w rzeczywistości pochodzi z ControllerContext, który można ustawić.

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

Ten działał dla mnie, pozwalając mi ustawić pozorne HttpContext na kontrolerze. –

32

utworzyć żądanie, reagowanie i umieścić je zarówno do HttpContext:

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

Pytanie dotyczy * klas podstawowych, tj. HttpRequestBase, a nie HttpRequest - nie wiem, dlaczego oba są potrzebne, a nawet bardziej irytujące, że są "zapieczętowane". Nie ma możliwości ustawienia LogonUserIdentity :( –

+0

Jeśli są one polecane przeze mnie, to nadal jest to możliwe za pośrednictwem zdalnego przekazywania, więc nie powinno to stanowić problemu – 0100110010101

+1

@ChrisKimpton: W ostateczności zawsze jest _reflection_ ;-) – Oliver

5

Oto przykład jak można to ustawić: Mocking HttpContext HttpRequest and HttpResponse for UnitTests (using Moq)

zanotować rozszerzenie metod, które naprawdę pomóc Aby uprościć korzystanie z tych kpiących klas:

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

Oto przykład jak napisać badanej jednostki przy użyciu MOQ, aby sprawdzić, że HttpModule działa zgodnie z oczekiwaniami: Unit Test for HttpModule using Moq to wrap HttpRequest

Aktualizacja: ten interfejs API został refactored

3

Oto jak użyłem ControllerContext do przekazania fałszywej aplikacji Pat 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

Dlaczego musisz podać fałszywą ścieżkę aplikacji? –

+0

Kod MVC wykona go i wygeneruje wyjątek zerowy, jeśli go tam nie ma. –

7

Dzięki użytkownik 0100110010101.

on pracował dla mnie, a tu miałem problem pisząc testcase kodu poniżej:

var currentUrl = Request.Url.AbsoluteUri; 

A oto linie, które rozwiązane Problem może być pomocny dla innych. Problem może być pomocny dla innych.

Powiązane problemy