2009-02-26 60 views
10

Tôi đã ghi đè phương thức OnActionExecuting của bộ điều khiển để đặt một số trạng thái bên trong dựa trên bộ lọc thực thiContextContext. Làm thế nào để kiểm tra điều này? Phương thức này được bảo vệ vì vậy tôi cho rằng tôi sẽ phải tăng cao hơn trong ngăn xếp cuộc gọi.Tôi làm cách nào để kiểm tra phương pháp OnActionExecuting của bộ điều khiển asp.net-mvc?

Tôi cần mã nào để kiểm tra điều này?

Tôi đang sử dụng mvc RC 1.

Chỉnh sửa: Tôi cũng đang sử dụng nunit.

Cảm ơn

Trả lời

15

Bạn cần thêm và sử dụng Trình truy cập riêng tư. Nhấp chuột phải vào lớp điều khiển của bạn và chọn Create Private Accessors từ trình đơn và thêm chúng vào dự án thử nghiệm của bạn. Khi đã ở trong dự án thử nghiệm của bạn, hãy tạo bộ điều khiển của bạn, sau đó tạo một trình truy cập cho nó. Phương thức này sẽ có sẵn trên accessor. Dưới đây là một thử nghiệm mẫu từ mã của riêng tôi:

/// <summary> 
///A test for OnActionExecuting 
///</summary> 
[TestMethod()] 
[ExpectedException(typeof(InvalidOperationException))] 
public void OnActionExecutingWindowsIdentityTest() 
{ 
    var identity = WindowsIdentity.GetCurrent(); 
    WindowsPrincipal principal = new WindowsPrincipal(identity); 
    var httpContext = MockRepository.GenerateStub<HttpContextBase>(); 
    httpContext.User = principal; 

    var actionDescriptor = MockRepository.GenerateStub<ActionDescriptor>(); 

    RouteData routeData = new RouteData(); 

    BaseController controller = new BaseController(); 
    BaseController_Accessor accessor = new BaseController_Accessor(new PrivateObject(controller)); 
    ControllerContext controllerContext = MockRepository.GenerateStub<ControllerContext>(httpContext, routeData, controller); 

    ActionExecutingContext filterContext = new ActionExecutingContext(controllerContext, actionDescriptor, new Dictionary<string, object>()); 

    accessor.OnActionExecuting(filterContext); 

} 

EDIT: Nếu bạn không sử dụng MSTest cho unit tests của bạn, bạn có thể phải tạo ra các bộ truy xuất bằng tay. Về cơ bản, bạn tạo một lớp bao bọc cho thấy các phương thức riêng/được bảo vệ của lớp được kiểm tra thông qua các phương thức công khai tương đương, chuyển một thể hiện của lớp đang kiểm tra tới trình bao bọc, và sau đó sử dụng sự phản chiếu từ lớp trình bao bọc để gọi riêng/được bảo vệ phương pháp trên lớp đang được kiểm tra.

public class MyClass 
    { 
     protected void DoSomething(int num) 
     { 
     } 
    } 

    public class MyClass_accessor 
    { 
     private MyClass privateObj; 

     public MyClass_accessor(MyClass obj) 
     { 
      this.privateObj = obj; 
     } 

     public void DoSomething(int num) 
     { 
      MethodInfo info = privateObj.GetType() 
             .GetMethod("DoSomething", 
                BindingFlags.NonPublic 
                | BindingFlags.Instance); 

      info.Invoke(obj,new object[] { num }); 
     } 
    } 
+0

Đây có phải là MSTest cụ thể không? Tôi đang sử dụng nunit và xunit atm. –

+0

Tôi chỉ hỏi vì tôi không thấy nút 'thêm người truy cập' và thực hiện tìm kiếm trên google mang đến cho tôi một số công cụ kiểm tra cụ thể của MS. –

+0

Vâng, tôi nghĩ vậy. Tôi cho rằng nó đòi hỏi ít nhất VS Pro để nó ở đó. Bạn có thể tạo một bằng tay và sử dụng sự phản chiếu để gọi phương thức thích hợp trên đối tượng riêng bên dưới. – tvanfosson

4

Gần đây tôi đã gặp sự cố tương tự và không thể tìm thấy giải pháp thỏa mãn. Vì vậy, tôi tạo ra chức năng trợ giúp của riêng tôi mà gọi OnActionExecuted và OnActionExecuting. Xem mã ở đây http://mkramar.blogspot.com.au/2012/06/onactionexecuting-and-onactionexecuted.html

+0

Lưu ý cách câu trả lời được chấp nhận bao gồm * mã và giải thích * và thiếu bất kỳ liên kết tự quảng cáo nào? Đó là mô hình cho câu trả lời chấp nhận được ở đây. –

+0

Tôi không yêu cầu người khác làm việc. Nhưng mã của bạn hoạt động. Tôi phải chỉnh sửa câu trả lời của bạn và thêm mã của bạn. Tôi đã kết hợp mã của bạn với http://stackoverflow.com/a/10316899/648076. Bây giờ thử nghiệm trông thật đẹp. –

0

Tôi đã cố gắng để làm điều này, nhưng tôi thực sự muốn kiểm tra kết quả của các tùy chỉnh thuộc tính vì nó áp dụng cho các điều khiển thực tế. Trong trường hợp của chúng tôi, chúng tôi đã có một thuộc tính ủy quyền đặt thuộc tính trên bộ điều khiển, bộ điều khiển sau đó sử dụng các thuộc tính. Mã của chúng tôi trông giống như sau:

// Create the controller to test 
PortalController controller = new PortalController(); 
var method = typeof(PortalController); 
var attribute = method.GetCustomAttributes(typeof(OrganizationContextFilter),true).Cast<OrganizationContextFilter>().SingleOrDefault(); 

// Set the controller Context with our fake objects on it 
controller.ControllerContext = this.GetDefaultControllerMock(controller); 

// Execute the Organization Context Filter 
var actionDescriptor = new Mock<ActionDescriptor>(); 
var context = Mock.Get(actionDescriptor.Object); 
context.Setup(s => s.ControllerDescriptor).Returns(new Mock<ControllerDescriptor>().Object); 

// Use the current controller Context 
ActionExecutingContext filterContext = new ActionExecutingContext(controller.ControllerContext, actionDescriptor.Object, new Dictionary<string, object>()); 
attribute.OnActionExecuting(filterContext); 

// We have to use this one, because it has the result of the Attribute execution 
PortalController pc = filterContext.Controller as PortalController; 
ActionResult result = pc.MethodToTest(); // Call the controller that had OnActionExecuting results 

Lợi ích của việc này là chúng tôi thực sự thực thi thuộc tính MVC tùy chỉnh trên bộ điều khiển mà chúng tôi đang thực sự thử nghiệm. Điều này cả hai bài tập mã thuộc tính tùy chỉnh và kiểm tra bộ điều khiển trong một tình huống giống như "thế giới thực".

+0

Chỉ cần một câu hỏi nhanh 2 năm sau khi thực tế - làm thế nào để thiết lập một thuộc tính điều khiển thông qua một thuộc tính có nguồn gốc? – VisualBean

Các vấn đề liên quan