gpt4 book ai didi

c++ - 更好的模仿?

转载 作者:太空宇宙 更新时间:2023-11-04 13:06:42 24 4
gpt4 key购买 nike

问题:

假设我有一个系统类,其中有一些组件。为了正确测试系统,我需要在系统类中保留一个指向组件的指针,并将组件设计为具有带有虚方法的接口(interface) IComponent。然后在测试中,我可以创建 IComponent 的模拟并将其提供给系统。

但在某些情况下我不想要这种方法。

还有其他使用模板并将组件指定为模板参数的技术,如下所示:

template <class Component>
class System
{
// ...
Component _component;
};

然后,在我的测试中,我可以创建系统并为其提供组件模拟,如下所示:

System<MockComponent> theSystem;

MockComponent 不一定继承自 IComponent,在我的方法中我不需要 IComponent,我只希望 MockComponent 有一些需要的方法,就像在 Component 中一样。

但这种方法的问题是我想指示 MockComponent 做什么,给它一些期望并告诉它返回什么。从测试中我无法访问 MockComponent 因为它存在于 System.如果System有一个Component的getter就可以了,但是有时候我不想在System中有一个Component的getter。然后,在测试中,我需要创建另一个类 MockSystem,并为其配备组件的 getter(并确保原始系统中的 _component 在“ protected ”部分)。

template <Class Component>
MockSystem : public System
{
public:
Component GetComponent() { return _component; }
};

然后,在测试中我可以:

MockSystem<MockComponent> theSystem;
MockComponent mockComponent = theSystem.GetComponent();
EXPECT_CALL(mockComponnent, ...);

这种方法效果很好。

但是...我想知道是否有办法稍微简化一下。

如果我有一种机制可以在编译时从 System 类生成 MockSystem 类呢?我的意思是我想获得具有所有模板参数的 getter 的系统类。

我知道模板元编程可以创造奇迹,但我不是 TPM 方面的专家。我已经阅读了一些示例并看到了 Boost::Hana 的实际应用,现在想知道这是否可行。

这里有没有人听说过或见过这样的框架?或者有其他方法吗?

最佳答案

您可以在模拟类上定义包装器 - 以允许访问模拟:

struct ComponentMock
{
MOCK_METHOD0(foo, int());
};
struct ComponentMockWrapper
{
static ComponentMock* mock;
int foo()
{
return mock->foo();
}
};
ComponentMock* ComponentMockWrapper::mock;

然后,在您的测试套件中:

class SystemTestSuite : public testing::Test
{
protected:
ComponentMock componentMock;
void SetUp() override
{
ComponentMockWrapper::mock = &componentMock;
}
System<ComponentMockWrapper> objectUnderTest;
};

然后像这样测试:

TEST_F(SystemTestSuite1, shallFooComponent)
{
EXPECT_CALL(componentMock, foo());
objectUnderTest.foo();
}

但是要注意这样的问题,比如 - 如果需要 2 个或更多 Component 该怎么办,或者如何跟踪可测试 Component 的生命周期...


也许更好的方法是牺牲一点封装以支持可测试性——即获得对组件的 protected 访问:

template <class Component>
class System
{
protected:
Component& getComponent(); // for UT only
};

并通过推广此功能允许 UT 中的公共(public)访问:

template <class Component>
class SystemTestable : public System<Component>
{
public:
using System<Component>::getComponent;
};

class SystemTestSuite : public testing::Test
{
protected:
SystemTestable<ComponentMock> objectUnderTest;
};

关于c++ - 更好的模仿?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41915949/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com