0

我正在使用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) {}
};

类的测试(使用QTestNumber可能如下所示:

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); }
};

这使我们能够推导出Tenfrom的测试,NumberTest以确保Ten不会无意中破坏Number's 接口的合同(例如,如果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不会自动捕获正确的析构函数,并且我这里没有虚拟析构函数。

继承的测试将同时运行基类的测试和它自己的测试,但是它将QVERIFY在基类测试的第二个断言()上失败,因为派生类Ten不提供构造函数(或任何其他方式)来提供测试的内容需要(Number具有特定值)。这个问题几乎只有在测试继承类的构造函数时(继承测试时)才会出现,我不确定如何最好地解决它。

我当然不想从父母的测试中挑选哪些测试将运行,哪些测试不运行,甚至更糟糕的是复制测试(省略构造函数的测试)。

另一方面,我能想到的唯一解决方案是从将被继承的测试类中省略构造函数的测试(并且对于从它派生的所有测试应该是通用的),并为基础创建单独的测试类仅用于测试其构造函数的类。毕竟构造函数并不是真正的接口的一部分。有没有其他方法可以(优雅地)解决这个问题?还是我一开始就完全错了?

4

0 回答 0