2013-12-13 11 views
9

Ich versuche, einige Tests auf meiner MVC-Anwendung auszuführen, aber ich habe eine Welt von Schwierigkeiten erlebt, es zur Arbeit zu bringen. Ich werde versuchen, es auf den Punkt zu bringen:Wie man HttpApplication/HttpContext zum Testen vortäuscht oder vortäuscht

ich RhinoMocks bin mit so etwas versuchen:

Setup:

MockRepository mocks = new MockRepository(); 
HttpContextBase _mockContext = mocks.FakeHttpContext(); 
mocks.SetFakeControllerContext(new LoginController()); 
HttpApplicationStateBase appState = MockRepository.GenerateStub<HttpApplicationStateBase>(); 
_mockContext.Expect(mc => mc.Application).Return(appState); 
HttpContext.Current = _mockContext.ApplicationInstance.Context; 

Hier ist die FakeHttpContext() Methode:

public static HttpContextBase FakeHttpContext(this MockRepository mocks) 
{ 
    HttpApplication app = mocks.PartialMock<HttpApplication>(); 

    HttpContextBase context = mocks.PartialMock<HttpContextBase>(); 
    HttpRequestBase request = mocks.PartialMock<HttpRequestBase>(); 
    HttpResponseBase response = mocks.PartialMock<HttpResponseBase>(); 
    HttpSessionStateBase session = mocks.PartialMock<HttpSessionStateBase>(); 
    HttpServerUtilityBase server = mocks.PartialMock<HttpServerUtilityBase>(); 

    SetupResult.For(context.ApplicationInstance).Return(app); 

    SetupResult.For(context.Request).Return(request); 
    SetupResult.For(context.Response).Return(response); 
    SetupResult.For(context.Session).Return(session); 
    SetupResult.For(context.Server).Return(server); 

    mocks.Replay(context); 
    return context; 
} 

Ich muss wirklich auf HttpContextBase.Request.AppRelativeCurrentExecutionFilePath zugreifen, aber es wird immer als null zurückgegeben. Das gleiche gilt für HttpContext.Current.Request.RequestContext.

Kann mir hier jemand helfen? Es ist sicher zu sagen, dass ich an diesem Punkt verzweifelt bin.

+0

Sie erzähle nicht, was das Problem ist? Erhalten Sie einen Fehler (welcher?)? Soweit ich sehen kann, ist das spezielle Setup 'Setup (c => c.Request.AppRelativeCurrentExecutionFilePath) sollte funktionieren, da 'Request' eine' virtuelle' Eigenschaft eines Typs ist, der selbst eine 'virtuelle' Eigenschaft' AppRelativeCurrentExecutionFilePath' besitzt. Was ist der Grund dafür, '_mockContext.SetupAllProperties();' zu sagen? Wollen Sie auch * andere * Eigenschaften einrichten? –

+0

@JeppeStigNielsen Ich habe meine Frage mit dem was ich gerade benutze aktualisiert. Ich kann es immer noch nicht zur Arbeit bringen. – Kehlan

Antwort

1

Versuchen Sie zunächst, die Verwendung von HttpContext.Current zu vermeiden, da die Verwendung einer statischen Methode das Testen wesentlich schwieriger macht, als Sie es jetzt herausgefunden haben. Wenn Sie ein Abhängigkeitsinjektions-Framework verwenden, injizieren Sie HttpContextBase in Ihren Konstruktor.

Für Ihr eigentliches Problem, in FakeHttpContext() versuchen

HttpRequestBase request = mocks.PartialMock<HttpRequestBase>(); 

zu

HttpRequestBase request = mocks.GenerateStub<HttpRequestBase>(); 

und dann in Ihrem Test ändern können Sie etwas tun:

_mockContext.Request.Stub(x=> x.AppRelativeCurrentExecutionFilePath).Return("foo"); 
var result = object.DoSomething(); 
Assert.AreEqual("foo",result); 

I don Ich denke, es ist ziemlich nützlich, sich teilweise über den HttpContext lustig zu machen, da Sie den fra testen werden stattdessen Testen Sie, dass das Framework Ihnen den richtigen Wert X basierend auf Wert Y und Z in dem HttpContext zurückgibt)

Eine andere Alternative besteht darin, eine Wrapperklasse um HttpContextBase zu erstellen, die Ihnen berechnete Werte zurückgibt. Z.B. HttpContextBaseWrapper.AppRelativeCurrentExecutionFilePath(), HttpContextBaseWrapper.RequestIpAddress(). Dadurch wird es einfacher, ALLE anderen Klassen zu testen, da sie sich nicht darum kümmern müssen, HttpContextBase und die Details zu verspotten. Sie müssen einfach Ihre HttpContextBaseWrapper-Klasse vortäuschen.

Edit:

ich auch würden Sie empfehlen Ihr einzuspritzen HttpRequestContext als gut, aber wenn das nicht möglich ist, dann können Sie die Request wie so in der FakeHttpContext Methode Stummel:

var requestContext = MockRepository.GenerateStub<RequestContext>(); 
request.RequestContext = requestContext; 
+0

Ich schätze diese Antwort wirklich. Ich habe das OP bearbeitet, da ich auf ein anderes Problem gestoßen bin. Ich muss auch 'HttpContext.Current.Request.RequestContext' vortäuschen. Gibt es irgendeine Chance, dass du mir dabei hilfst? – Kehlan

+0

Ich habe meine Antwort aktualisiert, damit Sie den RequestContext stubben können. –

+0

Ich bin mir nicht sicher, was 'HttpRequestContext' ist. Ich nehme an, du meinst 'RequestContext'. Nochmals vielen Dank! Ich werde es ausprobieren und sehen, wie es geht. – Kehlan

1

Warum erstellen Sie keine Abstraktionsklasse, die Aufrufe an die HttpContext-Basis enthält?

Dann können Sie etwas tun:

public class MyClass 
{ 
    private readonly IHttpContext _httpContext; 
    MyClass(IHttpContext httpContext) 
    { 
     _httpContext = httpContext; 
    } 

    public void Blaat() 
    { 
     _httpContext.DoYourThingsWithTheHttpContext(); 
    } 
} 

Angenommen, Sie Dependency Injection verwenden, suchen sonst am Fakes und Stubs Rahmen von Microsoft.