2009-09-23 45 views
92

Làm cách nào để sử dụng IoC Container để thử nghiệm đơn vị? Có hữu ích để quản lý mocks trong một giải pháp lớn (50+ dự án) bằng cách sử dụng IoC? Có kinh nghiệm gì không? Bất kỳ thư viện C# nào hoạt động tốt để sử dụng nó trong các bài kiểm tra đơn vị?Sử dụng IoC để kiểm tra đơn vị

+7

@Mark Seemann sẽ quá khiêm tốn để chỉ ra, nhưng nếu bạn quan tâm đến câu hỏi này, ít nhất bạn nên biết [AutoFixture] (http://autofixture.codeplex.com) –

+0

Có một điều tốt nói về mối quan hệ giữa DI và chế nhạo trên Vimeo bởi Miguel Castro: https://vimeo.com/68390510 – GregC

Trả lời

118

Nói chung, một DI Container không cần thiết cho thử nghiệm đơn vị vì kiểm tra đơn vị là tất cả về phân chia trách nhiệm.

Hãy xem xét một lớp có sử dụng Constructor tiêm

public MyClass(IMyDependency dep) { } 

Trong toàn bộ ứng dụng của bạn, nó có thể là có một sự phụ thuộc rất lớn graph ẩn đằng sau IMyDependency, nhưng trong một thử nghiệm đơn vị, bạn làm phẳng nó tất cả xuống một đơn Test Double.

Bạn có thể sử dụng mocks động như Moq hoặc RhinoMocks để tạo Test Double, nhưng không bắt buộc.

var dep = new Mock<IMyDependency>().Object; 
var sut = new MyClass(dep); 

Trong một số trường hợp, một auto-mocking container có thể được tốt đẹp để có, nhưng bạn không cần phải sử dụng cùng một DI container rằng việc áp dụng sản xuất sử dụng.

+12

đã đồng ý ... trừ khi mục tiêu thử nghiệm có một container IoC * là * phụ thuộc, các xét nghiệm của bạn không cần chúng .. bạn sẽ loại bỏ phần lớn đồ thị đối tượng khi bạn thực hiện các bài kiểm tra đơn vị của mình. –

+3

@Mark Seemann Điều này có ý nghĩa ... Nhưng về thử nghiệm tích hợp thì sao? Tức là, tôi đã chơi xung quanh với các bài kiểm tra giao diện người dùng và tôi phải đối mặt với tình huống khi tôi phải chia sẻ phần gốc. Có ý kiến ​​gì không? –

+3

@Arnis L .: Đối với các bài kiểm tra tích hợp, điều này ít quan trọng hơn. Bạn có thể chọn sử dụng DI Container để kết nối các thành phần, nhưng nếu có, bạn có thể cần cấu hình khác cho vùng chứa hơn trong ứng dụng đầy đủ - trừ khi bạn thực hiện Kiểm tra dưới da hoặc Kiểm tra hệ thống đầy đủ, trong trường hợp đó bạn có thể tái sử dụng cấu hình của ứng dụng của Vùng chứa. –

15

Làm cách nào để sử dụng Vùng chứa Ioc để kiểm tra đơn vị?

IoC sẽ thực thi mô hình lập trình mà sẽ làm cho kiểm tra đơn vị trong sự cô lập (tức là sử dụng mocks) dễ dàng hơn: sử dụng giao diện, không mới(), không có độc thân ...

Nhưng sử dụng các container IoC để thử nghiệm không thực sự là một yêu cầu, nó sẽ chỉ cung cấp một số cơ sở tiêm mocks nhưng bạn có thể làm điều đó bằng tay.

Có hữu ích khi quản lý mocks trong một giải pháp lớn (hơn 50 dự án) bằng IoC không?

Tôi không chắc chắn ý của bạn là gì bằng cách quản lý mocks bằng IoC. Dù sao, IoC container thường có thể làm nhiều hơn là chỉ tiêm mocks khi nói đến thử nghiệm. Và nếu bạn có hỗ trợ IDE phong nha mà làm cho tái cấu trúc có thể, tại sao không sử dụng nó?

Bất kỳ trải nghiệm nào?

Có, trên một giải pháp lớn, bạn cần nhiều hơn bao giờ hết một giải pháp không dễ bị lỗi và tái cấu trúc (tức là thông qua một loại IoC an toàn hoặc hỗ trợ IDE tốt).

13

Tôi thường sử dụng thùng chứa IoC trong các thử nghiệm của mình. Cấp, họ không phải là "kiểm tra đơn vị" theo nghĩa thuần túy. IMO Chúng có nhiều BDDish và tạo điều kiện tái cấu trúc. Các thử nghiệm đang có để cung cấp cho bạn sự tự tin để tái cấu trúc. Các bài kiểm tra viết kém có thể giống như đổ xi măng vào mã của bạn.

xem xét như sau:

[TestFixture] 
public class ImageGalleryFixture : ContainerWiredFixture 
{ 
    [Test] 
    public void Should_save_image() 
    { 
     container.ConfigureMockFor<IFileRepository>() 
      .Setup(r => r.Create(It.IsAny<IFile>())) 
      .Verifiable(); 

     AddToGallery(new RequestWithRealFile()); 

     container.VerifyMockFor<IFileRepository>(); 
    } 

    private void AddToGallery(AddBusinessImage request) 
    { 
     container.Resolve<BusinessPublisher>().Consume(request); 
    } 
} 

Có một vài điều xảy ra khi thêm một hình ảnh vào thư viện. Hình ảnh được thay đổi kích thước, hình thu nhỏ được tạo và các tệp được lưu trữ trên AmazonS3. Bằng cách sử dụng một container tôi có thể dễ dàng cô lập chỉ là hành vi tôi muốn kiểm tra, mà trong trường hợp này là một phần bền bỉ.

Một phần mở rộng thùng tự động chế giễu có ích khi sử dụng kỹ thuật này: http://www.agileatwork.com/auto-mocking-unity-container-extension/

+7

+1 cho cụm từ "như đổ xi măng vào mã của bạn ". Tôi đã bắt đầu sử dụng nó mọi lúc. –

2

Sử dụng container với khả năng để giải quyết các dịch vụ không đăng ký/uknown như SimpleInjector, DryIoc (mỏ của nó) có thể trở lại mocks cho các giao diện chưa thực hiện .

Điều đó có nghĩa là bạn có thể bắt đầu phát triển với triển khai đơn giản đầu tiên và các phụ thuộc giả lập của nó và thay thế chúng bằng thực tế khi bạn tiến bộ.

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