2013-04-25 5 views
6

Ich möchte meinen ServiceStack-Dienst testbar machen.In ServiceStack ist es möglich, das Request.Original Request-Objekt für Komponententests zu verspotten?

Derzeit habe ich:

[RequireFormsAuthentication] 
public object Delete(DeleteRequest request) 
{ 
    var originalRequest = (HttpRequest)Request.OriginalRequest; 
    var identity = originalRequest.RequestContext.HttpContext.User.Identity; 
    return othercode(identity); 
} 

Wo RequireFormsAuthentication ist

public class RequireFormsAuthenticationAttribute : RequestFilterAttribute 
{ 
    public override void Execute(IHttpRequest req, IHttpResponse res, object requestDto) 
    { 
     var originalRequest = (HttpRequest)req.OriginalRequest; 
     var identity = originalRequest.RequestContext.HttpContext.User.Identity; 
     if (!identity.IsAuthenticated) 
     { 
      res.StatusCode = (int)HttpStatusCode.Forbidden; 
      res.EndServiceStackRequest(skipHeaders: true); 
     } 
    } 
} 

Ich habe alle Abhängigkeiten von verwendeten verspottete out 'othercode()' und alles, was übrig bleibt, ist das Zeug, das in der ist Basisklasse Service. Gibt es ein Muster/Strategie/Ansatz/etwas, das ich vermisse, das macht das trivial?

Antwort

2

Ich entschuldige mich für die Verwendung von moq ... hatte bereits einige davon mit RhinoMocks getan. Ich denke, das Konzept sollte auf moq übertragen werden. This könnte eine gute Ressource sowie diese this sein.

Wie auch immer, ich denke, dass der Testcode unten beginnen sollte. Ihre Naht in spöttisch Request.OriginalRequest ersetzt die Service.RequestContext mit einem Mock-Objekt. Dann musst du alles darüber hinaus verspotten. Es wird eine Menge "Spott" sein und wenn du dich selbst wiederholst: "Habt ihr mich verspottet?" Jedes Mal, wenn du eine Klasse verspottest, ist es fast genussvoll.

[Test] 
public void testsomethign() 
{ 
    var mockedRequestContext = MockRepository.GenerateMock<IRequestContext>(); 
    var mockedHttpRequest = MockRepository.GenerateMock<IHttpRequest>(); 
    var mockedOriginalRequest = MockRepository.GenerateMock<HttpRequestBase>(); 
    var mockedOriginalRequestContext = MockRepository.GenerateMock<RequestContext>(); 

    mockedOriginalRequest.Stub(x => x.RequestContext).Return(mockedOriginalRequestContext); 
    mockedHttpRequest.Stub(x => x.OriginalRequest).Return(mockedOriginalRequest); 

    mockedRequestContext.Stub(x => x.Get<IHttpRequest>()).Return(mockedHttpRequest); 
    var service = new ServiceTests() 
    { 
     RequestContext = mockedRequestContext 
    }; 

    service.Delete(new DeleteRequest()); 
} 
+0

Das deckt ziemlich viel, eigentlich. Vielen Dank! Eine weitere Sache jedoch: Weißt du, wie ich das geschützte Mitglied 'Request' überschreiben kann? (Zeile 4 in meinem ersten Codeblock wird mit NRE fehlschlagen) – Robin

+0

Auch ... es scheint, 'HttpRequest' ist eine versiegelte Klasse und kann nicht verspottet werden. – Robin

+0

Yeah, HttpReqeust ist versiegelt Ich denke du kannst stattdessen auf HttpRequestBase umwandeln? Zeile 12 (mockedRequestContext.Stub (x => x.Get ()). Rückgabe (mockedHttpRequest)) Sollte es Ihnen ermöglichen, das Request-Mitglied zu verspotten. – paaschpa

7

So testen Sie mit Moq. Dieser Dienst sucht nach einem "Schlüssel" und einem "Wert" in der Abfragezeichenfolge und einem anderen Parameter im Anforderungs-DTO. Der Service gibt eine String-Antwort basierend auf dem angegebenen Wert zurück.

[Test] 
    public void MyTest() 
    { 
     var mockRequestContext = new Mock<IRequestContext>(); 
     var mockedHttpRequest = new Mock<IHttpRequest>(); 

     NameValueCollection querystring = new NameValueCollection(); 
     querystring.Add("myKey", "myValue"); 

     mockedHttpRequest.SetupGet(r => r.QueryString).Returns(querystring); 

     mockRequestContext.Setup(x => x.Get<IHttpRequest>()).Returns(mockedHttpRequest.Object); 

     AboutService service = new AboutService 
     { 
      RequestContext = mockRequestContext.Object, 
     }; 

     AboutResponse response = (AboutResponse)service.Any(new About 
     { 
      Company = "myOtherValue", 
     }); 

     Assert.AreEqual(0, response.QueryResult); 
     Assert.AreEqual("validResponse", response.Version); 
    } 
2

Überprüfen Sie den Namespace: ServiceStack.ServiceInterface.Testing.
Dort können Sie eine MockRequestContext finden, die Sie wie folgt verwendet werden:

var mockContext = new ServiceStack.ServiceInterface.Testing.MockRequestContext(); 
//do stuff to set it up if desired... 

AboutService service = new AboutService 
{ 
    RequestContext = mockContext 
};