首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >更好的MOCKing?

更好的MOCKing?
EN

Stack Overflow用户
提问于 2017-01-29 07:16:19
回答 1查看 49关注 0票数 1

问题:

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

但在某些情况下,我不想要这样的方法。

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

代码语言:javascript
复制
template <class Component>
class System
{
    // ...
    Component _component;
};

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

代码语言:javascript
复制
System<MockComponent> theSystem;

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

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

代码语言:javascript
复制
template <Class Component>
MockSystem : public System
{
public:
    Component GetComponent() { return _component; }
};

然后,在测试中我可以:

代码语言:javascript
复制
MockSystem<MockComponent> theSystem;
MockComponent mockComponent = theSystem.GetComponent();
EXPECT_CALL(mockComponnent, ...);

这种方法工作得很好。

但是..。我想知道是否有一种方法可以稍微简化一下。

如果我有一种机制,可以在编译时从System的类生成MockSystem的类,会怎么样?我的意思是,我想为所有的模板参数获取带有getter的系统类。

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

这里有没有人听说过或见过这样的框架?还是有别的方法呢?

关于YK

EN

回答 1

Stack Overflow用户

发布于 2017-02-13 18:06:46

你可以在你的mock类上定义包装器--允许访问mock:

代码语言:javascript
复制
struct ComponentMock
{
    MOCK_METHOD0(foo, int());
};
struct ComponentMockWrapper
{
    static ComponentMock* mock;
    int foo()
    {
        return mock->foo();
    }
};
ComponentMock* ComponentMockWrapper::mock;

然后,在您的TestSuite中:

代码语言:javascript
复制
class SystemTestSuite : public testing::Test
{
protected:
     ComponentMock componentMock;
     void SetUp() override
     {
        ComponentMockWrapper::mock = &componentMock;
     }
     System<ComponentMockWrapper> objectUnderTest;
};

并像这样测试:

代码语言:javascript
复制
TEST_F(SystemTestSuite1, shallFooComponent)
{
    EXPECT_CALL(componentMock, foo());
    objectUnderTest.foo();
}

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

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

代码语言:javascript
复制
template <class Component>
class System
{
protected:
    Component& getComponent(); // for UT only
};

并通过推广此功能在UT中允许公共访问:

代码语言:javascript
复制
template <class Component>
class SystemTestable : public System<Component>
{
public:
    using System<Component>::getComponent;
};

class SystemTestSuite : public testing::Test
{
protected:
     SystemTestable<ComponentMock> objectUnderTest;
};
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41915949

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档