2009-10-14 24 views
12

Có cách nào để sử dụng mocks hoặc fakes trong các bài kiểm tra đơn vị của bạn mà không cần phải sử dụng tiêm phụ thuộc hoặc đảo ngược hoặc kiểm soát?Mocking mà không có IoC hoặc Dependency Injection

Tôi tìm thấy cú pháp này có thể được sử dụng với TypeMock Isolator (http://learn.typemock.com/). Mặc dù đó là một sản phẩm thương mại, vì vậy tôi đã hy vọng rằng các khung công tác khác (như RhinoMocks) sẽ giới thiệu cú pháp như vậy ở một giai đoạn nào đó.

/// Can mock objects WITHOUT DEPENDENCY INJECTION. 

var hand = Isolate.Fake.Instance<Hand>(); 
var mouth = Isolate.Fake.Instance<Mouth>(); 
Isolate.Swap.NextInstance<Hand>().With(hand); 
Isolate.Swap.NextInstance<Mouth>().With(mouth); 
... 
//notice we're not passing the mocked objects in. 
var brain = new Brain(); 
brain.TouchIron(iron); 
... 

Điều này rất hấp dẫn đối với tôi loại cú pháp này, tất cả đều diễn ra tự động. Chúng ta có thể tạo ra một bộ não ở đó mà không cần các phụ thuộc bắt buộc và khung mocking sẽ tự động thay thế các phụ thuộc cho các đối tượng giả. Bất kỳ cơ thể nào nhìn thấy loại điều này ở bất cứ nơi nào khác?

Não lớp constructor trông như bây giờ bằng cách sử dụng cú pháp ở trên này,

public Brain() 
{ 
    _hand = new Hand(); 
    _mouth = new Mouth(); 
} 

Trong khi ví dụ dependency injection sẽ trông như thế này,

public Brain(IHand hand, IMouth mouth) 
{ 
    _hand = hand; 
    _mouth = mouth; 
} 

Cảm ơn.

Trả lời

11

Nếu bạn có lựa chọn, bạn hầu như luôn luôn phơi bày một hàm tạo để cho phép các phụ thuộc được tiêm vào. Bạn vẫn có thể giữ cho các nhà xây dựng thuận tiện (mặc dù một số người cho rằng bạn không nên):

public Brain() : this(new Hand(), new Mouth()) { } 

Điều đó nói rằng, ngoài việc Isolator bạn có thể kiểm tra được xây dựng mới nhất của Pex (0.17), trong đó bao gồm moles rằng cung cấp một cơ chế tương tự như Swap của Isolator.

+1

Đồng ý, các nhà xây dựng mặc định chuyển tiếp đến thực tế là một kỹ thuật rất hữu ích. –

4

Cá nhân tôi không nghĩ đây là một điều tốt.

Với tôi, DI cung cấp tốt hơn chỉ là testability, do đó, nó là không hợp lý để đi từ nó ngay cả khi một số công cụ cho phép làm điều đó. Xem thêm this question và câu trả lời đầu tiên cho nó.

+2

TUYẾN ĐỔI TUYỆT ĐỐI - nhưng hãy xem xét hàng triệu dòng mã cũ có thể không thực tế để di chuyển nhưng có thể hưởng lợi từ thử nghiệm đơn vị! – mtazva

4

AFAIK, TypeMock là khung duy nhất cho phép kịch bản này và có thể sẽ diễn ra trong một thời gian dài. Lý do là nó sử dụng một cách tiếp cận hoàn toàn khác để chế nhạo.

Tất cả các khung mocking khác sử dụng tạo kiểu động để làm điều tương tự mà bạn có thể thực hiện trong mã: mở rộng và ghi đè. Trong trường hợp này, manual and dynamic mocks are basically the same thing, bởi vì họ dựa vào việc có thể mở rộng các loại trừu tượng.

LoạiMock sử dụng kỹ thuật hoàn toàn khác, vì nó sử dụng API lược tả .NET (không được quản lý) để chặn cuộc gọi đến bất kỳ loại nào. Đây là nhiều hơn khó triển khai hơn, do đó, không nên ngạc nhiên khi đó là cam kết thương mại.

Trong mọi trường hợp, TypeMock so với phần còn lại của thế giới là một cuộc tranh luận cũ và rất sống động. Here's one take on it (hãy chắc chắn cũng đọc các ý kiến).

2

Moles, khung đường vòng đi kèm với Pex, cũng cho phép thực hiện việc này ... nhưng có cú pháp khác.

MHand.New = (me) => { 
    new MHand(me) { 
     TouchIronIron = iron => {} 
    };  
}; 

Lưu ý rằng ví dụ của bạn không nhất quán.

0

Cảm ơn vì điều đó. Nó đã cho tôi đống để suy nghĩ về. Tôi đang làm việc trên một ứng dụng chưa được thiết kế để thử nghiệm và hiện không có bài kiểm tra đơn vị. Tôi nghĩ rằng giải pháp cuối cùng sẽ là cơ cấu lại nó dần dần, và sử dụng Rhino Mocks. Tôi đã sử dụng đống Rhino trước đây, và nó đã rất tuyệt.

Tôi đã bắt đầu nhận ra rằng giải pháp 'tất cả trong' có lẽ là tốt nhất, tức là Rhino sẽ buộc cơ cấu lại sử dụng Inversion of Control đầy đủ sẽ buộc các quyết định thiết kế tốt.

Bất kể khung mocking nào tôi sử dụng tôi sẽ thoải mái rằng bản thân mình có thể đưa ra quyết định thiết kế tốt vì tôi đã thực hiện nhiều công việc như thế này trước đây, nhưng những người khác làm việc trên mã chưa thực hiện kiểm thử đơn vị trước đó buộc họ sử dụng IoC là tốt hơn.

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