2010-03-05 30 views
20

Có đúng là những cái cuống Rhino Mocks và mocks chỉ tốt cho các giao diện, không phải là các lớp cụ thể? Tôi đã dành khá nhiều thời gian để làm cho đoạn mã này hoạt động. Tôi không mong đợi pubSubClient bị bướng bỉnh luôn gọi phương thức Send từ lớp. Phương thức đó có một số phụ thuộc và ném ngoại lệ.Rhino Mocks stubs và mocks chỉ tốt cho giao diện?

[Test] 
public void Test01() 
{ 
    PubSubMessage psm = new PubSubMessage(); 
    var pubSubClient = MockRepository.GenerateStub<PubSubClient>(); 
    pubSubClient.Stub(x => x.Send(psm)).IgnoreArguments().Return(null); 
    // actual PubSubClient Send method throws exception 
    // the rest of the test is skipped... 
} 

Tuy nhiên, khi tôi trích xuất giao diện và chạy thử nghiệm tương tự với IPubSubClient, có vẻ như nó hoạt động như mong đợi.

Điều đó có nghĩa là tôi phải trích xuất giao diện cho mọi lớp học mà tôi muốn giả lập/làm tê liệt với tê giác? Hoặc tôi thiếu một cái gì đó, kỹ thuật hay khái niệm?

CẬP NHẬT: OK, Có vẻ như tôi đã tìm ra phần nào tôi nhớ da diết: Rhino Mocks không thể đánh chặn các cuộc gọi đến các phương pháp không ảo. Vì vậy, tôi đoán tôi có hoặc là sử dụng giao diện hoặc thực hiện mọi phương pháp trên lớp bê tông ảo. Vui lòng sửa tôi nếu có tùy chọn khác.

Trả lời

23

Câu trả lời của Bryan về việc sử dụng phần mocks không chính xác. Đó không phải là những gì một phần mocks cho.

Câu trả lời của Jon Erickson chủ yếu là chính xác: Rhino Mocks và Moq không thể chặn các cuộc gọi không ảo, cũng như không thể chặn các phương thức hoặc thuộc tính tĩnh. Điều đó có nghĩa là bạn không thể giả mạo những điều sau đây:

DateTime.Now; // static property, can't fake static property 
someClass.SomeNonVirtualMethod(); // can't fake non-virtual method 
sealedClass.Foo(); // can't fake anything on sealed classes 
Utilities.SomeStaticMethod(); // can't fake static methods 
someList.Any(); // can't fake extension methods like Linq's .Any() 

LoạiMock có thể giả mạo những thứ này, như Jon đã đề cập.

Cần lưu ý rằng có một khuôn khổ giả mạo bổ sung có thể chặn tất cả các cuộc gọi: Microsoft Moles framework. Nó hoạt động giống như TypeMock, nó sử dụng API lược tả .NET để chặn các cuộc gọi.

Các nốt ruồi là miễn phí (hiện tại). Nó cũng là phiên bản beta. Các nốt ruồi chỉ hoạt động với Microsoft Pex tools. Và API của nó rõ ràng kém hơn API tinh tế, tinh tế của TypeMock.

+4

Nếu bạn tuyên bố rằng một phần mocks không phải cho một cái gì đó nó là hữu ích hơn để nói những gì họ đang có trong phản ứng của bạn. Một phần mocks được dự định để mô phỏng chỉ một phần của một lớp, điều này làm cho chúng tiện dụng (và cần thiết) để thử ra một lớp trừu tượng, nơi một mô hình bình thường không thể xử lý này. Điều này cho phép thử nghiệm các phương thức trừu tượng. Một giả lập một phần (ít nhất là trong Rhino) sẽ giả lập bất kỳ lớp nào và không bị giới hạn trong các lớp Abstract, tuy nhiên hãy lưu ý nếu có mã thực thi sẽ được gọi khi trả về. –

+0

(cảnh báo necro): Tôi vừa phát hiện ra lớp học của bạn thậm chí không cần phải trừu tượng để tạo các phương thức ảo! Một điều nhỏ như vậy, nhưng tôi chưa bao giờ xem xét nó trước đây :-) – Heliac

1

Mô phỏng một phần cho phép bạn mô phỏng chức năng của lớp bê tông. Xem: http://www.ayende.com/wiki/Rhino+Mocks+Partial+Mocks.ashx

+0

Tôi sợ một phần mocks không hoàn toàn làm điều đó. Chúng hữu ích khi chế nhạo một số phương thức chưa được thực hiện trong các lớp trừu tượng, nhưng nếu có thực hiện, nó vẫn được gọi. Nói cách khác, trong ví dụ của tôi, thay thế MockRepository.GenerateStub () bằng MockRepository.GeneratePartialMock () không thay đổi gì cả. –

+1

làm cho phương pháp của bạn trở nên ảo. –

3

Bạn phải tạo các phương thức ảo. Rhino mocks (và hầu hết các khung cách ly khác) sử dụng các lớp proxy để tạo ra các nhánh/mocks.

Nếu bạn sử dụng TypeMock Isolator bạn có thể thử bất cứ điều gì vì khuôn khổ cô lập này sử dụng .NET Profiler API để tạo cuống của nó/chế giễu

+0

+1. Như OP đã đề cập trong bản cập nhật của mình, các phương thức phải là ảo. Điều này đúng với Moq, và (tôi tin) mọi khung cách ly .NET ngoại trừ TypeMock Isolator. Việc sửa chữa rẻ và dễ dàng là làm cho các phương thức ảo (hoặc trích xuất một giao diện). – TrueWill

0

Tôi không nghĩ rằng có một cách khác để làm điều này khác hơn là làm cho bất kỳ phương pháp nào bạn muốn giả lập - tôi tin rằng cách thức mocks của các lớp cụ thể được tạo ra là bằng cách phân lớp động lớp bê tông đang được mô phỏng và ghi đè các phương thức đã cho với hành vi bạn chỉ định trong bài kiểm tra, vì vậy điều này đòi hỏi một phương pháp ảo để hoạt động chính xác.

2

Về cơ bản là chính xác và thường là thực hành tốt. Tuy nhiên, nó chỉ thực sự là hữu ích cho một loại mã hóa cụ thể.

Đừng nghĩ rằng đối tượng là thứ mà một số 'sức mạnh cao hơn' có thể thao tác. Thay vào đó, hãy nghĩ chúng là 'người' tự trị có thể gửi tin nhắn cho nhau. Một giao diện đại diện cho các tin nhắn được gửi bởi một đối tượng duy nhất.

Sau đó, bạn sử dụng mocks để xác minh rằng các tin nhắn chính xác đã được gửi đi, không cung cấp việc triển khai giả mạo các phụ thuộc.

Lý tưởng nhất là bạn không tạo giao diện khớp chính xác với lớp hiện có - thay vào đó, lớp tiêu thụ giao diện khai báo nhu cầu của nó dưới dạng giao diện.

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