2010-04-09 111 views
5

假設我有一個C++類,像這樣:C++和依賴注入單元測試

class A 
{ 
    public: 
     A() 
     { 

     } 

     void SetNewB(const B& _b) { m_B = _b; } 

    private: 
     B m_B; 
} 

爲了單元測試這樣的事情,我將不得不打破B. A的依賴。由於A類持有到一個實際的對象而不是一個指針,我將不得不重構這段代碼來獲取一個指針。此外,我需要爲B創建一個父接口類,以便在測試SetNewB時可以傳入我自己的B的假。

在這種情況下,不使用依賴注入進行單元測試會使現有代碼進一步複雜化?如果我讓B成爲一個指針,我現在介紹堆分配,現在有一段代碼負責清理它(除非我使用ref計數指針)。另外,如果B是一個相當平凡的類,只有一些成員變量和函數,爲什麼要爲它引入一個全新的接口,而不是僅僅使用B的實例進行測試?

我想你可能會認爲使用接口重構A更容易。但是有些情況下可能需要緊密耦合兩個類?

回答

8

我想你對單元測試的想法太過分了。在這種情況下,A和B是一個單位,即A沒有B就不能存在。首先,測試B並確保它通過了所有B特定的單元測試,然後一旦通過,測試A並確保它表現它應該如何。

+0

有趣的是,我想我是在想象單元測試需要所有類彼此完全分離。但正如你所指出的,A絕對需要B來工作;所以他們實際上是一個單位。 – lhumongous 2010-04-09 18:22:54

0

根據你如何使用B,你可以使用std :: auto_ptr而不是ref-counting指針。只要您不需要將對B的引用傳遞給可以工作並需要最少代碼更改的其他內容即可。

2

如果B真的是注入到A的依賴項,那麼你應該考慮一些其他選項。首先是在建設時注入B

class A 
{ 
    public: 
     A(const B& _b) : m_B(_b) {} 

    private: 
     const B& m_B; 
}; 

如果你真的想你A對象的生命週期過程中修改B,然後問自己,如果你真的的B所有者。如果沒有,傳遞一個指針,並假設通過它的人負責其生命週期 - 儘管這是一條棘手的路線,並且可能需要您使用ref-counts指針。

如果你想要做的是爲自己拿一份B的副本,那麼你可以在B上定義clone()方法。如果要使用B中包含的信息創建自己的對象,則可以在構造函數中注入MyBFactory,並將其與B一起使用。