我正在编写封装硬件驱动程序(用户空间)的单元测试,我正在使用的设计模式如下:
class uio
{
virtual uint32_t readbit(...);
virtual bool writebit(...);
// other driver related functions
// ...
};
class uio_test : public uio
{
virtual uint32_t readbit(...) override { /* don't talk to hardware, send back test data */ }
virtual bool writebit(...) override { /* don't talk to hardware, write test data */ }
};
class spi : public uio
{
// spi related functions
};
class i2c : public uio
{
// i2c related functions
};
我的问题是如何根据模块(真实程序与gtest)使spi和uio从uio或uio_test中正确继承。我看过条件例如:
template<bool test>
class spi : public std::conditional<test, uio_test, uio>
这将适用于所有对象仅从主要派生的世界。
/* main.cpp */
spi<false> s;
s.init();
s.writebit();
/* gtest_main.cpp */
spi<true> s;
ASSERT_TRUE(s.init());
ASSERT_EQ(/* read/write test bits, etc*/);
然而,uio派生的对象在整个程序中用于其他专门的类,我看不到条件构造的好方法,例如:
class temperature_monitor
{
createBuses();
spi<???>* spictrl_;
};
/* perhaps derive test classes, easy since most high level objects are singletons */
temperature_monitor::createBuses()
{
if (testmode)
spictrl_ = new spi<true>;
else
spictrl_ = new spi<false>;
}
希望这对所有人来说都是泥泞的。在他们被问到之前我会回答几个问题:
Q值。预处理器条件怎么样?
一个。不,如果可能的话,永远不会。
Q值。你为什么要编写像spi这样的低级别位冲击驱动程序的单元测试?
一个。为什么不,有一些内部逻辑正在进行,我宁愿在单元测试中捕获错误而不是尝试调试一天中缺少0的愚蠢。
答案 0 :(得分:0)
我认为你想要的是战略模式。 uio
提供非虚拟接口和指向实现的指针。您认为有一个虚拟接口,并向uio
对象提供正常或测试实例,而不是尝试在中间插入继承。使用策略模式甚至允许您插入其他实现。