我们可以使用新的C ++关键字final
声明最终/密封的非可继承类。
class Generator final
{
};
此类可能继承自其他,可能有也可能没有虚拟(继承或未继承)。但是,如何使它final
,但允许一个类继承它?
我们主要需要从真实类派生一个模拟类(有或没有后期绑定,因此virtual
并不重要)。如何使它工作:
class MockGenerator : Generator{};
但是不允许任何其他继承?
答案 0 :(得分:4)
一种可能性:使用define for final并在生成测试环境时将其定义为空。
#ifdef MOCK
#define CLASS_FINAL
#else
#define CLASS_FINAL final
#endif
编辑:我同意utnapistim的评论:这不是推荐,只是技术上的可能性(但至少比#define final
好。)
答案 1 :(得分:4)
但是,如何让它成为最终,但允许一个类继承它?
那是不可能的。
我们主要需要从真实类派生一个模拟类(有或没有后期绑定,因此虚拟并不重要)。
如果课程是最终的,那么不需要从中派生。如果您做需要从中派生,它不是最终的。选一个。
修改:您可以为您的课程添加限制,但这些限制自费用于该界面:
class Generator // not final
{
Generator(); // the only accessible constructor is private
// whitelist who has access to this constructor
friend class MockGenerator;
public:
// no public constructors here except for copy & move
Generator(Generator&);
Generator(Generator&&);
...
// provide controlled access to the private constructor
static Generator make_generator() { return Generator(); }
// rest of API here
};
这是一个允许它的工厂和MockGenerator专业化来调用它的构造函数的类。这是以阻止琐碎建筑为代价的。
旧代码(不再可编译):
Generator instance;
新代码(由私有构造函数强制执行):
auto instance = Generator::make_generator();
答案 2 :(得分:0)
如果您需要为单元测试创建模拟类,那么您可以尝试Typemock Isolator++。因为它可以轻松处理final
类。您甚至不需要在生产代码中更改某些内容(例如创建单独的模拟类)。我已经创建了简单的测试来演示它:
class Generator final
{
public:
int foo()
{
return 0;
}
};
TEST_METHOD(TestFinal)
{
Generator* generator = FAKE<Generator>();
WHEN_CALLED(generator->foo()).Return(1);
int result = generator->foo();
Assert::AreEqual(1, result);
}
希望它对你有用。