2017-06-15 6 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() { /*...*/ } 

はFoo .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.inl Foo.inlはプライベートでも含まれる(unittestのよう)Fooの定義が必要なだけがfoo.hを使用 ユーザーが(パッケージ」で提供されていませ含めます")。

関連する問題