抽象クラスをテストしたい:
class Fu
{
public:
virtual void func(int count, std::string data)
{
for(int i = 0; i < count; i++)
{
pureFunc(data);
}
}
virtual void pureFunc(std::string data) = 0;
}
次にfuncをテストするために、引数count
を使用してpureFunc data
を呼び出すことを確認します。私が行ったことは、Fu
をサブクラス化し、Mock
を作成することです。
class TestFu : public Fu
{
public:
virtual void pureFunc(std::string data) override {};
}
class MockFu : public TestFu
{
public:
MOCK_METHOD1(pureFunc, void(std::string));
}
そしてテストするために私は次のことをします:
MockFu mock_fu;
EXPECT_CALL(mock_fu, pureFunc("test"))
.Times(10);
mock_fu.func(10, "test");
しかし、私は上記が有効なパターンかどうか疑問に思っていました。私の心配は、クラスではなくモッククラスをテストしていること、またはそれが非抽象サブクラスであることです。
総括する:
あなたはここでかなり多くのことを尋ねていますが、あなたが説明することについて私の意見を共有させてください。
モッククラスの一般的な使用法は、別のクラスをテストするために必要であり、モッククラスの状態が変更されているかどうかを確認する必要がある場合です(インターフェースのより重い実装の代わりに)。
あなたが説明するケースはもちろん有効ですが、テスト自体は役に立たないと主張したいと思います。典型的な例では、pureFuncはプライベートであると想定しますが、それほど重要ではありません。現在テストしているのは実装であり、動作ではありません。テストする必要があるのは、funcが行うことです(つまり、何かを返すか、クラスの状態を変更することによって)。
より明確にするために。あなたの例では、forcループでfunc runをcount/2にして、コードをpureFunc自体で2回実行することができます(奇数では機能しませんが、引数として考慮してください。単体テストは失敗しますが、 、オブジェクトの状態は同じです。ユニットテストが失敗し始めることなく、クラスと実装を変更できるようにする必要があります。実装を変更するたびにユニットテストを変更する必要がある場合は、何か問題が発生しています。
代わりに何ができますか?さて、あなたはあなたの抽象クラスの実装を持っています。 funcをテストして、期待どおりに機能するかどうかを確認できます。 (実際に公開されている場合は、pureFunc)。