2012-06-13 29 views
0

爲了教育目的,我應該如何設置IWindsorContainer的模擬,以便我可以進行單元測試執行註冊?如何模擬windsor容器以測試註冊

假設我有這樣的方法:

public void MakeRegistration<S, T>(IWindsorContainer container) 
    where S : class 
    where T : class, S 
{ 
    container.Register(Component.For<S>().ImplementedBy<T>().LifeStyle.Transient); 
} 

我想寫一個單元測試它,使用起定量:

var container = new Mock<IWindsorContainer>(MockBehavior.Strict); 
container.Setup(c => c.Register(
     Component.For<IFoo>() 
     .ImplementedBy<Foo>() 
     .LifeStyle.Transient)); 

var registrar = new MyRegistrar(); 
registrar.MakeRegistration<IFoo, Foo>(container.Object); 

上述失敗,如預期的,但我m好奇如何正確地測試它。

我可以使用真正的容器而不是模擬,並驗證它解析了2個不同的類的實例,但我認爲它不是「純粹的」單元測試,因爲它實際上依賴於外部代碼的工作(windsor容器本身)。

正如我所說,這是理論上的,所以如果需要的話不在問題的範圍之內。

+1

如果您在假容器上測試註冊,此測試的目的是什麼?它什麼都不測試。 –

回答

1

你只需要一個實施Foo登記對服務IFoo斷言這將是純粹的測試(實例:採用NSubstitute,因爲我沒有使用MOQ一段時間)。

[ Test ] 
public void Should_register_implemenation_of_Foo_for_service_IFoo() 
{ 
    var container = Substitute.For<IWindsorContainer>(); 

    container.Register(Component.For<IFoo>().ImplementedBy<Foo>()); 

    container.Received().Register(Arg.Is<IRegistration[]>(x => Test(x))); 

} 

private bool Test(IRegistration[] registrations) 
{ 
    var fooRegistration = (ComponentRegistration<IFoo>) registrations[ 0 ]; 

    return fooRegistration.Implementation == typeof(Foo); 
} 
public interface IFoo {} 

public class Foo : IFoo {} 

我知道你說這個問題理論上的,而且要問以下問題,使這些新的TDD假設你必須做的事情這種方式是很重要的。

如果測試規定組件是如何實現它的目標或者它應該只是測試一個組件實際上實現它的目標

IMO我覺得在編寫集成測試時有更多的價值,它表明在確保在依賴性上調用某些方法時,連線是正確的。

+0

謝謝,你讓我以正確的方式,我應該攔截傳遞給Register方法的IRegistrations,並檢查它。 –

+0

要回答你的其他陳述,如果要求是「應註冊爲LifeStyle.Transient」,那麼我要求的TDD POV就是有意義的。 –

+1

雖然這是一種行爲,只要你有一些接受標準來測試它,如果你的生活方式是暫時的,或者沒有,只要它有效,這應該無關緊要。如果你的標準迫使你改用短暫的生活方式,那麼很好,但是它是否應該規定你應該使用短暫的生活方式?這就是你從TDD走開並開始尋找BDD的地方。一個測試可能是「不應該返回同一個xyz實例」,不同之處在於你的測試並不是說你必須使用瞬態生活方式,但它確實表示我每次都想要一個不同的對象。 – Bronumski