我需要你的帮助。以下:
X类定义了组成命令的方法。这些命令被发送到 UART 设备。 X 类必须是静态的。类X的方法必须根据状态在状态机(Boost MSM)中调用。
现在我必须编写一个测试来检查方法是否被正确调用。这样我还可以检查所有转换表是否正确。
我使用GMock进行测试。但是,模拟类继承的类必须是虚拟的(根据 GMock)。这在生产代码中是不可能的(嵌入式设备、小内存等)。
这就是为什么我决定编写一个 X 类的虚拟对象。它与原始 X 类具有相同的方法,但在这种情况下它们可以是虚拟的,因为测试是在计算机上执行的。
现在测试必须创建状态机的实例,这不是问题。
真正的问题是我必须继承状态机中的虚拟classX来调用函数,以便mock可以检查方法是否可以正确调用。
不幸的是,这是不可能的,因为一旦我从 DummyClassX 继承,VTable 就会在生产代码中创建。
不幸的是,我想不出应该如何测试状态机和函数调用的解决方案。有没有办法阻止创建 VTable?
这里我创建了另一个草图以使其更容易理解。
但是,模拟类继承的类必须是虚拟的(根据 GMock)。
谁说的? ;-) 您似乎跳过了 gtest 文档中的模拟非虚拟方法。
这将需要将一些现有代码重新编写为模板,但肯定可以完成。
想象一下下面的课程
struct Dep
{
void doStuff() const{};
};
以及一个依赖它的人:
struct S
{
S(const D& d_) : d(d_) {}
void doStuff() const { d.doStuff(); }
Dep d;
};
后者可以改写为以下形式
template<typename D>
struct S
{
S(const D& d_) : d(d_) {}
void doStuff() const { d.doStuff(); }
D d;
};
这样就可以注入依赖了。
那么,让我们创建一个模拟:
struct DMock
{
MOCK_METHOD(void, doStuff,(), (const));
};
问题是,模拟是不可复制的,并且
std::ref
的技巧在这里不起作用,除非传递函数对象。
因此,必须提供额外的间接级别。 如果您的代码通过指针或引用接受依赖项,您可能需要跳过此步骤。
struct DMockWrapper
{
DMock* impl;
void doStuff() const { impl->doStuff(); }
};
因此,整个测试将如下所示:
TEST(X, Y)
{
DMock dm;
S<DMockWrapper> s{DMockWrapper{&dm}};
EXPECT_CALL(dm, doStuff);
s.doStuff();
}