2012-02-13 14 views
12

Tôi rất, rất mới để kiểm tra đơn vị và đang cố gắng để viết một bài kiểm tra cho một phương pháp khá đơn giản:Làm cách nào để thực hiện kiểm tra đơn vị để kiểm tra phương pháp kiểm tra tiêu đề yêu cầu?

public class myClass : RequireHttpsAttribute 
{ 
    public override void OnAuthorization(AuthoizationContext filterContext) 
    { 
     var request = filterContext.HttpContext.Request; 
     var header = Convert.ToBoolean(request.Headers["Special-Header-Name"]); 

     if (!(header || request.IsSecureConnection)) 
     { 
      HandleNonHttpsRequest(filterContext); 
     } 
    } 
} 

Phương pháp này, mà được thừa hưởng từ RequireHttpsAttribute, kiểm tra nếu một tiêu đề chắc chắn là món quà từ một trang , nếu nó bị thiếu hoặc sai, và trang không an toàn, sau đó nó sẽ gọi HandleNonHttpsRequest, nếu không nó sẽ không làm gì cả.

Chúng tôi đang sử dụng Moq và Nunit để thử nghiệm. Tôi đã tìm thấy một số tài nguyên để giúp xây dựng một giảHttpContext với Moq, nhưng thành thật mà nói, tôi không chắc chắn làm thế nào để sử dụng nó hoặc đi đâu trong các bài kiểm tra đơn vị của tôi để đảm bảo HttpContexts giả hoặc đang không gây ra phương thức HandleNonHttpsRequest.

Tôi thực sự đánh giá cao bất kỳ hướng dẫn nào về vấn đề này.

Trả lời

20
// arrange 
var context = new Mock<HttpContextBase>(); 
var request = new Mock<HttpRequestBase>(); 
var headers = new NameValueCollection 
{ 
    { "Special-Header-Name", "false" } 
}; 
request.Setup(x => x.Headers).Returns(headers); 
request.Setup(x => x.HttpMethod).Returns("GET"); 
request.Setup(x => x.Url).Returns(new Uri("http://www.example.com")); 
request.Setup(x => x.RawUrl).Returns("/home/index"); 
context.Setup(x => x.Request).Returns(request.Object); 
var controller = new Mock<ControllerBase>(); 

var actionDescriptor = new Mock<ActionDescriptor>(); 
var controllerContext = new ControllerContext(context.Object, new RouteData(), controller.Object); 
var filterContext = new AuthorizationContext(controllerContext, actionDescriptor.Object); 
var sut = new myClass(); 

// act 
sut.OnAuthorization(filterContext); 

// assert 
Assert.IsInstanceOfType(filterContext.Result, typeof(RedirectResult)); 
var redirectResult = (RedirectResult)filterContext.Result; 
Assert.AreEqual("https://www.example.com/home/index", redirectResult.Url); 
+1

+1 cho chỉ ra các phần AAA của bài kiểm tra. – CodingWithSpike

+0

Cảm ơn bạn! Điều này đã gửi cho tôi đúng hướng để có được một số thử nghiệm thành công. – Dredj

1

Có, tôi muốn sử dụng Moq và tạo Mock<AuthorizationContext>. Bạn sẽ cần một loạt các đối tượng giả để thiết lập yêu cầu giả, đáng chú ý nhất là chỉ định một NameValueCollection của các tiêu đề giả.

var request = new Mock<HttpRequestBase>(); 
request.SetupGet(c => c.Headers).Return(new NameValueCollection{ /* initialize values here */}); 
request.SetupGet(c => c.IsSecureConnection).Return(/*specify true or false depending on your test */); 

var httpContext = new Mock<HttpContextBase>(); 
httpContext.SetupGet(c => c.Request).Return(request.Object); 


var filterContext = new Mock<AuthorizationContext>(); 
filterContext.SetupGet(c => c.HttpContext).Return(httpContext.Object); 

var myclass = new myClass(); 
myClass.OnAuthorization(filterContext.Object); 

(xin lỗi nếu cú ​​pháp hoặc sử dụng là hơi off; làm điều này từ đỉnh đầu của tôi)

Bạn có thể cần phải đi vào và nhạo báng bất kỳ bổ sung thành viên trên filterContext rằng HandleNonHttpsRequest gọi. Tôi có hai khuyến nghị cho việc này, vì đôi khi nó có thể là một rắc rối nếu phương pháp bạn đang thử nghiệm đang thực hiện rất nhiều công cụ phức tạp trên filterContext: 1) kiểm tra trực quan và, nếu nó thẳng về phía trước, hãy thử tất cả các phần được gọi 2) tạo myClass.OnAuthorizationRequest, nhưng không triển khai bất kỳ mã nào khác ngoài lệnh gọi đến HandleNonHttpsRequest. Tiếp tục chạy thử nghiệm và sửa các thành viên bị thiếu/không chính xác cho đến khi thử nghiệm trôi qua. Sau đó, thực hiện logic thực tế của bạn cho OnAuthorizationRequest, kiểm tra và sửa lỗi (rửa lại) cho đến khi nó trôi qua.

0

tôi gặp phải một vấn đề với the accepted solution sử dụng ASP.NET MVC 4. Để giải quyết nó tôi chế giễu thuộc tính Items bối cảnh http nếu không sut.OnAuthorization đã gây ra một đối tượng là undefined ngoại lệ:

MockHttpContext.Setup(x => x.Items) 
    .Returns(new System.Collections.Generic.Dictionary<object, object>());