2017-06-15 65 views
0

我正在使用template dependency injection在代碼中測試一個依賴於非虛擬方法的類,該代碼不能更改。我想maintain the class's declaration and definition separately像以前一樣。兩種可能的模板實例在編譯時都是已知的,這可能導致較少的膨脹/編譯時間。由於在鏈接描述的,這可以通過在.cpp文件的末尾明確實例已知的模板變形來實現:主要.cpp文件之外的顯式模板實例化

// "Foo.cpp" 
#include "Foo.h" 
// definition of Foo<T>::f() etc. 
template class Foo<Bar>; 
template class Foo<MockBar>; 

然而,這引起在生產代碼的測試引用。此外,如果我嘗試轉發宣告MockBar,我會收到「使用不完整類型」錯誤。如果我包含MockBar.hFoo.cpp,那麼我需要確保我的構建過程也被調整爲包含並鏈接任何相關的測試代碼與Foo(例如gmock),這似乎是錯誤的。如果我將template class Foo<MockBar>實例化爲Foo_test.cpp,那麼我會爲其上的方法獲取未定義的引用鏈接錯誤(但對於預期的實例沒有錯誤)。我想我錯過了關於實例化過程的一些東西。

我該如何保持單獨的標題方法,同時分離測試和生產代碼?

+0

你可以有一個「私人」Foo.inl,你可以在測試中使用。 – Jarod42

+0

你能澄清你的意思嗎? –

+0

我的意思是在Foo.cpp和FooTest.cpp中,你有'#include「foo.inl」'(定義在foo.inl中,Foo.h現在只有前向聲明(public interface))。 – Jarod42

回答

1

您可以用不同的方式分割你的文件,並讓使用者實現對你的測試,是這樣的:

foo.h中

template <typename T> class Foo 
{ 
    // member declaration ... 
}; 

Foo.inl

#include "Foo.h" 

template <typename T> 
void Foo::bar() { /*...*/ } 

富.cpp

#include "Foo.inl" 
#include "Bar.h" 

// Instantiations 
template class Foo<Bar>; 
// ... 

而在FooTest.cpp

#include "Foo.inl" 
#include "MockBar.h" 

template class Foo<MockBar>; 

// Test Foo<MockBar> ... 

所以普通用戶只能使用需要的Foo定義(如單元測試)包括Foo.inl Foo.inl可以是私有包括(未在「包提供了foo.h 用戶「)。