2013-04-25 41 views
6

Tôi muốn dịch vụ ServiceStack của mình có thể kiểm tra được.Trong ServiceStack có thể giả lập đối tượng Request.OriginalRequest cho các bài kiểm tra đơn vị không?

Hiện nay tôi có:

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

đâu RequireFormsAuthentication là

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

Tôi đã chế giễu ra tất cả các phụ thuộc được sử dụng bởi 'othercode()' và tất cả những gì còn lại là những thứ đó là trong Dịch vụ lớp cơ sở. Có một mô hình/chiến lược/cách tiếp cận/cái gì tôi đang thiếu mà làm cho tầm thường này?

Trả lời

2

Tôi xin lỗi vì đã không sử dụng moq ... đã thực hiện một số việc này bằng RhinoMocks. Tôi nghĩ rằng khái niệm nên chuyển sang moq. This có thể là một tài nguyên tốt cũng như điều này this.

Dù sao, tôi nghĩ mã kiểm tra bên dưới sẽ giúp bạn bắt đầu. Đường nối của bạn vào chế nhạo Request.OriginalRequest sẽ thay thế Service.RequestContext bằng một đối tượng giả. Sau đó, bạn chỉ cần giả lập tất cả mọi thứ vượt ra ngoài đó. Nó sẽ là rất nhiều 'chế nhạo' và nếu bạn lặp lại với chính mình 'Bạn đang chế nhạo tôi' mỗi khi bạn thử một lớp học thì nó gần như là thú vị.

[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

Đó bao gồm khá nhiều, trên thực tế. Cảm ơn! Một điều nữa, tuy nhiên: bạn có biết làm thế nào tôi có thể ghi đè lên thành viên được bảo vệ 'Yêu cầu'? (dòng 4 trong khối mã đầu tiên của tôi sẽ thất bại với NRE) – Robin

+0

Ngoài ra ... có vẻ như 'HttpRequest' là một lớp niêm phong và không thể bị chế nhạo. – Robin

+0

Vâng, HttpReqeust được niêm phong Tôi nghĩ bạn có thể truyền tới HttpRequestBase thay thế? Dòng 12 (mockedRequestContext.Stub (x => x.Get ()). Return (mockedHttpRequest)) Nên cho phép bạn giả lập thành viên Request. – paaschpa

7

Dưới đây là cách kiểm tra bằng Moq. Dịch vụ này tìm kiếm một "khóa" và "giá trị" trong chuỗi truy vấn và một tham số khác trong DTO yêu cầu. Dịch vụ trả về một chuỗi phản hồi dựa trên giá trị đã cho.

[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

Hãy nhớ kiểm tra không gian tên: ServiceStack.ServiceInterface.Testing.
Trong đó bạn có thể tìm thấy một MockRequestContext mà bạn có thể sử dụng như sau:

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

AboutService service = new AboutService 
{ 
    RequestContext = mockContext 
};