私はクラスBarを使用するクラスFooを持っています。 (私はFooの外でバーを必要としないので、ないの参照を)ので、私はunique_ptrを使用して、バーだけはFooで使用され、fooが管理バーです:モックするためのunique_ptrの依存性注入
using namespace std;
struct IBar {
virtual ~IBar() = default;
virtual void DoSth() = 0;
};
struct Bar : public IBar {
void DoSth() override { cout <<"Bar is doing sth" << endl;};
};
struct Foo {
Foo(unique_ptr<IBar> bar) : bar_(std::move(bar)) {}
void DoIt() {
bar_->DoSth();
}
private:
unique_ptr<IBar> bar_;
};
は、これまでのところは良い、これは正常に動作します。私は、コードのユニットテストしたい場合しかし、私は問題を抱えている:
namespace {
struct BarMock : public IBar {
MOCK_METHOD0(DoSth, void());
};
}
struct FooTest : public Test {
FooTest() : barMock{ make_unique<BarMock>() }, out(std::move(barMock)) {}
unique_ptr<BarMock> barMock;
Foo out;
};
TEST_F(FooTest, shouldDoItWhenDoSth) {
EXPECT_CALL(*barMock, DoSth());
out.DoIt();
}
モックオブジェクトはFooのfoは転送され、失敗したなモックの期待を設定したため、テストが失敗しました。 DIの
可能なオプション:shared_ptrのことで
- :IBARを参照して
- (バーオブジェクトはFooの間、他のすべてのものを共有していない)、この場合、多すぎる:オプションではありません( BarはFooの外部には格納されないので、作成されたBarオブジェクトは破壊され、Fooは参照が残っています)
- by unique_ptr:提示された方法ではテストできません
- 値渡しでは不可能ですoccure - unique_ptrと同じ問題)。
私が得た唯一の解決策は、fooがBarMockのもっぱら所有者になる前にBarMockに生のポインタを格納することで、すなわち:
struct FooTest : public Test {
FooTest() : barMock{new BarMock} {
auto ptr = unique_ptr<BarMock>(barMock);
out.reset(new Foo(std::move(ptr)));
}
BarMock* barMock;
unique_ptr<Foo> out;
};
はきれいな解決策はありませんか?静的依存関係注入(テンプレート)を使用する必要がありますか?
の)、ダウンキャストあなたは、[この回答](http://stackoverflow.com/questions/7616475/can-google-mock-a-method-with-a-smart-pointer読書に興味がある可能性があり-return-type/11548191#11548191)。 –
@πάνταῥεῖ:リンクありがとうございます。私はすでにそれを見てきましたし、unique_ptrをパラメータとして取るメソッドでも動作しますが、コンストラクタにこのアプローチを適用できるかどうかはわかりません。 – Quarra