GMock / 虚拟函数 / Boost MSM 如何正确组合?

问题描述 投票:0回答:1

我需要你的帮助。以下:

X类定义了组成命令的方法。这些命令被发送到 UART 设备。 X 类必须是静态的。类X的方法必须根据状态在状态机(Boost MSM)中调用。

现在我必须编写一个测试来检查方法是否被正确调用。这样我还可以检查所有转换表是否正确。

我使用GMock进行测试。但是,模拟类继承的类必须是虚拟的(根据 GMock)。这在生产代码中是不可能的(嵌入式设备、小内存等)。

这就是为什么我决定编写一个 X 类的虚拟对象。它与原始 X 类具有相同的方法,但在这种情况下它们可以是虚拟的,因为测试是在计算机上执行的。

现在测试必须创建状态机的实例,这不是问题。

真正的问题是我必须继承状态机中的虚拟classX来调用函数,以便mock可以检查方法是否可以正确调用。

不幸的是,这是不可能的,因为一旦我从 DummyClassX 继承,VTable 就会在生产代码中创建。

不幸的是,我想不出应该如何测试状态机和函数调用的解决方案。有没有办法阻止创建 VTable?

这里我创建了另一个草图以使其更容易理解。

c++ boost embedded state-machine googlemock
1个回答
0
投票

但是,模拟类继承的类必须是虚拟的(根据 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();
}

https://godbolt.org/z/nefhjzbKd

© www.soinside.com 2019 - 2024. All rights reserved.