私は使用していますが、この問題は、私の意見では、単に特定QTest
というよりも一般的です。QTest
単純なクラスがあるとします:
class Number
{
Number() {}
Number(int i) : m_Value(i) {}
int value() const { return m_Value; }
private:
int m_Value = 0;
};
そして、から派生する別のクラスNumber
:
class Ten : public Number
{
public:
Ten() : Number(10) {}
};
QTest
クラスのテスト (を使用) は次のNumber
ようになります。
class NumberTest : public QObject
{
Q_OBJECT
public:
using QObject::QObject;
private slots:
void testNumberConstructor()
{
std::shared_ptr<Number> num = createNumber();
QVERIFY(num->value() == 0);
std::shared_ptr<Number> num = createNumber(1);
QVERIFY(num->value() == 1);
}
private:
virtual std::shared_ptr<Number> createNumber() { return std::make_shared<Number>(); }
virtual std::shared_ptr<Number> createNumber(int i) { return std::make_shared<Number>(i); }
};
そして、それによりTen
fromのテストを導出して、が不注意に のインターフェイスの契約を破らないNumberTest
ようにすることができます (たとえば、呼び出された仮想メソッドが によってオーバーライドされた場合、または後でそのように変更された場合に重要になる可能性があります)。Ten
Number
Number
Ten
class TenTest : public NumberTest
{
Q_OBJECT
public:
using NumberTest::NumberTest;
private slots:
void testTenConstructor()
{
Ten num;
QVERIFY(num.value() == 10);
};
private:
virtual std::shared_ptr<Number> createNumber() override { return std::make_shared<Number>(new Ten()); }
virtual std::shared_ptr<Number> createNumber(int i) override { return std::make_shared<Number>(new Ten()); } //<<< This is the problem!
};
注:正しいデストラクタを自動キャプチャせず、ここに仮想デストラクタがないshared_ptr
ため、使用します。unique_ptr
継承されたテストは、基本クラスのテストとそれ自体のテストの両方を実行しますが、基本クラスのテストの 2 番目のアサート ( QVERIFY
) で失敗しTen
ます。 (Number
特定の値を持つ)が必要です。この問題は、継承されたクラスのコンストラクターをテストするとき (テストを継承するとき) にのみ発生し、最適な解決方法がわかりません。
私は確かに、親のテストからどのテストが実行され、どのテストがテストをコピーしないか、さらに悪いことに (コンストラクターのテストを省略して) チェリー ピックしたくありません。
一方、私が考えることができる唯一の解決策は、継承されるテストクラスからコンストラクターのテストを省略し(それから派生するすべてのテストに共通する必要があります)、ベース用に別のテストクラスを作成することですコンストラクターをテストするクラスのみ。結局、コンストラクターは実際にはインターフェイスの一部ではありません。この問題を (エレガントに) 解決する他の方法はありますか? それとも、そもそも完全に間違っていますか?