2012-02-12 20 views
21

Tôi đang cố gắng sử dụng lâu đài Windsor trong các thử nghiệm tự động của tôi như vậy:Trong Lâu đài Windsor 3, ghi đè lên một đăng ký thành phần hiện tại trong một thử nghiệm đơn vị

Trên mỗi bài kiểm tra:

  • Chức năng Setup() tạo ra một Thùng chứa Windsor, đăng ký việc triển khai mặc định của từng thành phần
  • Chức năng Test truy cập các thành phần thông qua phương pháp IWindsorContainer.Resolve<T> và kiểm tra hành vi của chúng
  • TearDown() chức năng phân phối của thùng chứa Windsor (và bất kỳ thành phần được tạo ra)

Ví dụ, tôi có thể có 15 thử nghiệm truy cập các thành phần gián tiếp dẫn đến việc tạo ra một thành phần IMediaPlayerProxyFactory. Chức năng SetUp đăng ký thực hiện đủ tốt IMediaPlayerProxyFactory, vì vậy tôi không có gánh nặng bảo trì khi đăng ký điều này trong mỗi 15 thử nghiệm.

Tuy nhiên, hiện tôi đang viết bài kiểm tra Test_MediaPlayerProxyFactoryThrowsException, xác nhận hệ thống của tôi xử lý một lỗi một cách thanh lịch từ thành phần IMediaPlayerProxyFactory. Trong phương pháp thử nghiệm tôi đã tạo ra thực hiện mô hình đặc biệt của tôi, và bây giờ tôi muốn tiêm nó vào khuôn khổ:

this.WindsorContainer.Register(
           Component.For<IMediaPlayerProxyFactory>() 
              .Instance(mockMediaPlayerProxyFactory) 
          ); 

Nhưng Windsor ném một Castle.MicroKernel.ComponentRegistrationException, với thông điệp "Hiện đã là một thành phần với tên đó. "

Có cách nào để tôi có thể tạo mockMediaPlayerProxyFactory làm phiên bản mặc định cho IMediaPlayerProxyFactory, loại bỏ thành phần đã được đăng ký không?


Theo documentation, Lâu đài Windsor 3 cho phép ghi đè đăng ký, nhưng tôi chỉ có thể tìm thấy một ví dụ:

Container.Register(
    Classes.FromThisAssembly() 
     .BasedOn<IEmptyService>() 
     .WithService.Base() 
     .ConfigureFor<EmptyServiceA>(c => c.IsDefault())); 

ConfigureFor là một phương pháp của lớp BasedOnDescriptor. Trong trường hợp của tôi, tôi không sử dụng số FromDescriptor hoặc BasedOnDescriptor.

Trả lời

55

Có hai điều mà bạn phải làm gì để tạo ra một thể trọng:

  1. Gán cho nó một tên duy nhất
  2. Gọi IsDefault phương pháp

Vì vậy, để có được ví dụ để làm việc :

this.WindsorContainer.Register(
          Component.For<IMediaPlayerProxyFactory>() 
             .Instance(mockMediaPlayerProxyFactory) 
             .IsDefault() 
             .Named("OverridingFactory") 
         ); 

Bởi vì tôi dự định sử dụng giá trị trọng lượng này trong nhiều bài kiểm tra, tôi đã tạo ra phương pháp mở rộng của riêng tôi:

public static class TestWindsorExtensions 
{ 
    public static ComponentRegistration<T> OverridesExistingRegistration<T>(this ComponentRegistration<T> componentRegistration) where T : class 
    { 
     return componentRegistration 
          .Named(Guid.NewGuid().ToString()) 
          .IsDefault(); 
    } 
} 

Bây giờ ví dụ có thể được đơn giản hóa để:

this.WindsorContainer.Register(
          Component.For<IMediaPlayerProxyFactory>() 
             .Instance(mockMediaPlayerProxyFactory) 
             .OverridesExistingRegistration() 
         ); 


Sau Sửa

Phiên bản 3.1 giới thiệu các IsFallback phương pháp. Nếu tôi đăng ký tất cả các thành phần ban đầu của tôi với IsFallback, thì mọi đăng ký mới sẽ tự động ghi đè các đăng ký ban đầu này. Tôi đã đi xuống con đường đó nếu chức năng có sẵn vào thời điểm đó.

https://github.com/castleproject/Windsor/blob/master/docs/whats-new-3.1.md#fallback-components

+0

đặt tên và gọi phương thức '.IsDefault' không bắt buộc đối với việc triển khai thực sự, ngoài việc đó, rất hay! – bevacqua

+1

Cảm ơn bạn đã cập nhật câu trả lời. –

1

Không sử dụng lại vùng chứa của bạn trong các thử nghiệm. Thay vào đó, đặt nó thành null trong TearDown() và khởi tạo lại nó cho mỗi thử nghiệm thực tế.

+0

Xin lỗi, tôi không được rõ ràng. Tôi loại bỏ các container trong 'TearDown()', và tôi lại khởi tạo nó trong 'SetUp()'. Tôi sẽ thay đổi phần giới thiệu của mình để thử và làm rõ hơn. –

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