CPP FakeIt库具有多重继承性

时间:2015-11-10 21:03:10

标签: c++ unit-testing googletest googlemock

我将GoogleMock与FakeIt进行比较,以便编写单元测试。我喜欢FakeIt over GoogleMock,因为我来自Java背景,FakeIt坚持接近Mockito / JMock语法,这使得使用库更容易编写和使用。维护。

但FakeIt GIT home(https://github.com/eranpeer/FakeIt)表示它不支持MultipleInheritance,并且应用程序即时测试具有多重继承的代码。我不必支持钻石继承,所以我想知道它是否只是不支持多重继承的那个方面,还是其他方面也不支持?

2 个答案:

答案 0 :(得分:2)

不幸的是,似乎任何类型的多重继承都不受支持,即使它只是一个"接口"它统一了其他几个"接口",例如:

struct IA { virtual void a() = 0; };
struct IB { virtual void b() = 0; };
struct IC : public IA, public IB {};
fakeit::Mock<IC> mock; // error :(

(使用std::is_simple_inheritance_layout<T>

进行检查 但是,我确实为这个问题找到了一些解决方法,至少对于简单的场景:

class MockC : public IC {
public:
    MockC(IA& a, IB& b) : m_a(a), m_b(b) {}
    void a() override { return m_a.a(); };
    void b() override { return m_b.b(); };
private:
    IA& m_a;
    IB& m_b;
};

fakeit::Mock<IA> mockA;
fakeit::Mock<IB> mockB;
MockC mockC(mockA.get(), mockB.get());
// Use mockA and mockB to set up the mock behavior the way you want it.
// Just make sure not to use mockC after they go out of scope!

答案 1 :(得分:2)

这是另一种解决方法,不需要您制作特殊的模拟类。您需要做的是模拟每个基类,并通过将派生类强制转换为每个接口的引用,将其应用于派生类的实例。您确实需要将模拟应用于类的实例。这是一个示例:

class I1
{
public:
    virtual int one() = 0;
};

class I2
{
public:
    virtual int two() = 0;
};

class Both : public I1, public I2
{
public:
    virtual int one()
    {
        return 0;
    }
    virtual int two()
    {
        return 0;
    }
    virtual int three()
    {
        return one() + two();
    }
};

我们有分别具有纯虚方法I1I2的纯接口one()two(),它们都由Both实现。您可能会猜到,Both的设计是为了产生错误的答案来演示该模拟。这是Google Test测试中的模拟:

TEST(both_mock, three)
{
    Both both;
    Mock<I1> mock1((I1&)both);
    Mock<I2> mock2((I2&)both);

    When(Method(mock1, one)).Return(1);
    When(Method(mock2, two)).Return(2);

    ASSERT_EQ(both.three(), 3);
}

这有效并通过。这样做的好处是您不需要创建特殊的模拟类,而可以使用继承多个类的实际类。缺点是...

  • 派生类(在这种情况下为both)必须是可实例化的(例如,您不能使用继承自其他抽象类或接口的抽象类或接口来做到这一点)。
  • 如果进一步子类化两个接口的子类(例如class More : public Both),则每个接口/基类仍需要一个模拟,并且不能模拟Both,{{ 1}},或任何其他派生类。