我将GoogleMock与FakeIt进行比较,以便编写单元测试。我喜欢FakeIt over GoogleMock,因为我来自Java背景,FakeIt坚持接近Mockito / JMock语法,这使得使用库更容易编写和使用。维护。
但FakeIt GIT home(https://github.com/eranpeer/FakeIt)表示它不支持MultipleInheritance,并且应用程序即时测试具有多重继承的代码。我不必支持钻石继承,所以我想知道它是否只是不支持多重继承的那个方面,还是其他方面也不支持?
答案 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();
}
};
我们有分别具有纯虚方法I1
和I2
的纯接口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}},或任何其他派生类。