2009-04-22 20 views
6

Tôi đang cố gắng xác minh hành vi của ứng dụng ASP.Net MVC của tôi khi xảy ra lỗi không mong muốn. Cụ thể, tôi đang cố gắng xác minh rằng người dùng được chuyển hướng đến trang lỗi mà tôi đã xác định cho ứng dụng của mình. Vấn đề tôi gặp phải là tôi không thể xác minh hành vi của phương thức điều khiển như mong đợi.Làm thế nào tôi có thể kiểm tra đơn vị hành vi của thuộc tính HandleError cho một phương thức điều khiển?

Đối với các thử nghiệm hành vi bình thường, tôi tạo đối tượng quy tắc nghiệp vụ giả và chuyển nó cho bộ điều khiển của tôi và sau đó xác minh ViewResult từ phương thức bộ điều khiển mà tôi muốn kiểm tra. Điều này làm việc tốt cho mục đích của tôi khi mọi thứ hoạt động như mong đợi. Tuy nhiên, khi tôi ném ngoại lệ từ phương thức quy tắc nghiệp vụ, ngoại lệ được thực hiện thông qua kết quả phương pháp bộ điều khiển thay vì được xử lý (phương pháp điều khiển có thuộc tính 'HandleError') bởi bộ điều khiển sao cho ViewResult phù hợp cho trang lỗi của tôi được trả lại.

Có cách nào để xác minh hành vi của thuộc tính HandleError trong thời trang này không? Hoặc tôi đang đi về điều này hoàn toàn sai? Tôi nhận ra rằng tôi có thể sử dụng Selenium (thử nghiệm trong trình duyệt sẽ tấn công vào máy chủ thực tế) để xác minh hành vi trong một trình duyệt thực tế, nhưng chế nhạo các loại thử nghiệm này cho phép tôi thực hiện điều này nhanh hơn và với chi phí thấp hơn nhiều ...

Mã Kiểm tra Mẫu:

// WidgetController.Index() makes a call to GetWidgets to retrieve a 
// List<Widget> instance. 

// this works as expected since the appropriate ViewResult is returned 
// by the controller 
public void TestWidgetControllerIndex_NoResultsFound() 
{ 
    var mockBR = new Mock<IBusinessRules> { CallBase = true }; 
    mockBR.Setup(br=>fr.GetWidgets()).Returns(new List<Widget>());  
    WidgetController controller = new WidgetController(mockBR.Object); 
    ViewResult result = (ViewResult)controller.Index(); 
    Assert.AreEqual("Index", result.ViewName); 
    Assert.AreEqual(0, 
     ((WidgetIndexViewData)result.ViewData.Model).Widgets.Count); 
} 

// this test is unable to reach the assertion statements due to the problem 
// outlined above. WidgetController.Index has the HandleError attribute 
// properly applied and the behaviour via the interface is as expected 
public void TestWidgetControllerIndex_BusinessRulesExceptionEncountered() 
{ 
    var mockBR = new Mock<IBusinessRules> { CallBase = true }; 
    mockBR.Setup(br=>fr.GetWidgets()).Throws<ApplicationException>();  
    WidgetController controller = new WidgetController(mockBR.Object); 
    ViewResult result = (ViewResult)controller.Index(); 
    // The ApplicationException thrown by the business rules object bubbles 
    // up to the test through the line above. I was expecting this to be 
    // caught and handled by the HandleError filter (which would then let 
    // me verify the behaviour results via the assertion below).. 
    Assert.AreEqual("Error", result.ViewName); 
} 

Tôi muốn đánh giá cao bất kỳ đề xuất nào về những gì tôi có thể làm sai hoặc liệu tôi có đang tiếp cận điều này theo hướng hoàn toàn sai không. Tôi đưa ra giả định rằng thử nghiệm ở cấp phương thức điều khiển là cách thích hợp để đến đây vì đó là nơi mà thuộc tính HandleError được áp dụng .. (Nếu tôi cần kiểm tra ở cấp ứng dụng, có thể thực hiện điều đó thông qua tương tự không đối tượng instantiated thay vì sử dụng một cái gì đó như Selenium?)

Cập nhật Tôi đã đi đến kết luận rằng tôi không nên thử nghiệm chức năng liên quan đến thuộc tính HandleError trên mỗi hành động điều khiển. Tôi không thực sự quan tâm đến nó, tôi chỉ muốn đảm bảo rằng lỗi được xử lý (từ quan điểm thử nghiệm của tôi cho dù mã tùy chỉnh của nó hoặc thư viện MVC không tạo ra sự khác biệt, đó là chức năng mà tôi muốn xác minh).

Điều tôi đã làm là gói các hành động điều khiển của mình trong các khối try/catch để buộc xem lỗi được trả về do phương thức (chứ không phải thuộc tính ErrorHandler bắt lỗi khi nó rời khỏi phương pháp). Bằng cách này tôi có thể khẳng định trong bài kiểm tra đơn vị của tôi rằng lỗi được xử lý đúng cách với phản hồi thích hợp. Tôi không hài lòng với chiều dài thêm rằng điều này thêm vào các phương thức điều khiển của tôi, nhưng nó cho phép tôi cung cấp thông báo lỗi thân thiện, cụ thể cho người dùng (tôi đang sử dụng một phương pháp mở rộng để hiển thị phản hồi và thực hiện ghi nhật ký). (Vì vậy, có những ưu và khuyết điểm đối với phương pháp thử/nắm bắt chắc chắn ..)

Tôi không 100% tích cực rằng đây là cách sạch sẽ nhất, nhưng nó đạt được mục tiêu của tôi là có thể xác minh lỗi đó được xử lý thông qua bộ điều khiển đơn vị kiểm tra (nhanh) thay vì phải thực hiện các kiểm tra trong trình duyệt (chậm). Vì vậy, về cơ bản nó là đủ tốt cho đến bây giờ, cho đến khi tôi có thể tìm thấy một giải pháp sạch hơn. Tôi đã quyết định tặng tiền thưởng nếu có ai gặp vấn đề tương tự và đã tìm ra giải pháp tốt hơn ..

Trả lời

6

Tôi nghĩ bạn không thể kiểm tra đơn vị này. Bạn cũng không muốn. Bạn có thể kiểm tra rằng ngoại lệ dự kiến ​​được ném bởi một phương pháp điều khiển. Sử dụng sự phản chiếu, bạn có thể kiểm tra rằng hành động hoặc bộ điều khiển có thuộc tính mà bạn mong đợi nó có và thuộc tính đó có các giá trị thuộc tính mong đợi nhất định.Tuy nhiên, công việc chặn ngoại lệ và thực thi thuộc tính là hành vi của khung công tác chứ không phải mã của bạn. Nói chung bạn không nên kiểm tra mã không phải của bạn (khung công tác).

1

Vâng, tôi đồng ý với Tim. Những gì bạn mô tả là một bài kiểm tra tích hợp. Hành vi của HandleErrorAttribute phụ thuộc vào hành vi ASP.NET cơ bản, chẳng hạn như bạn có lỗi tùy chỉnh hoặc tắt trong web.config hay không.

Đối với bài kiểm tra đơn vị của bạn, bạn chỉ có thể sử dụng phản ánh để xác minh rằng thuộc tính là hiện tại.
Đội MVC có các unit test cho các HandleErrorAttribute, do đó bạn không cần phải viết những. :) Sau đó, chỉ cần kiểm tra thủ công hành động của bạn để đảm bảo đó là hành vi bạn muốn. Miễn là bạn không bao giờ thay đổi/loại bỏ các thuộc tính, hành vi không nên thay đổi.

Nếu bạn muốn tự động hoá các thử nghiệm tích hợp, bạn có thể sử dụng Watin hoặc Selenium để tự động hóa một yêu cầu trình duyệt thực tế để đảm bảo hành vi ứng dụng của bạn không thay đổi.

+0

Đây chính là phương pháp mà tôi đã thực hiện. (Ví dụ, sử dụng Selenium để xác minh hành vi thông qua một bài kiểm tra tích hợp ..) –

+0

sẽ quy tắc này là tương tự khi bạn tùy chỉnh HandleErrorAttribute ví dụ, chúng tôi đã tùy chỉnh các HandleErrorAttribute để xử lý nó với ELMAH? Tôi có nên chỉ đơn giản là khẳng định trong đơn vị kiểm tra cho dù một ngoại lệ được ném bởi bộ điều khiển hay không và để lại điều Elmah như là một phần của thử nghiệm tích hợp mà chúng tôi đã viết bằng cách sử dụng Selenium – byte

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