问题:
假设我有一个类系统,里面有一些组件。为了正确测试系统,我需要在System类中保留一个指向组件的指针,并将组件设计为具有一个具有虚方法的接口IComponent。然后在测试中,我可以创建IComponent的模拟并将其提供给系统。
但在某些情况下,我不想要这样的方法。
还有使用模板并将组件指定为模板参数的其他技术,如下所示:
template <class Component>
class System
{
// ...
Component _component;
};然后,在我的测试中,我可以创建一个系统,为它提供一个组件的模拟,如下所示:
System<MockComponent> theSystem;MockComponent不一定要从IComponent继承,在我的方法中,我不想要IComponent,我只希望MockComponent有一些需要的方法,就像在Component中一样。
但这种方法的问题是,我想指示MockComponent做什么,给它一些期望,并告诉它要返回什么。在测试中,我无法访问MockComponent,因为它驻留在系统中。如果系统有一个组件的getter,那么就可以了,但有时我不想在系统中有一个组件的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的实际应用,现在我想知道这是否可行。
这里有没有人听说过或见过这样的框架?还是有别的方法呢?
关于YK
发布于 2017-02-13 18:06:46
你可以在你的mock类上定义包装器--允许访问mock:
struct ComponentMock
{
MOCK_METHOD0(foo, int());
};
struct ComponentMockWrapper
{
static ComponentMock* mock;
int foo()
{
return mock->foo();
}
};
ComponentMock* ComponentMockWrapper::mock;然后,在您的TestSuite中:
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的生命周期……
也许更好的方法是牺牲一点封装,以支持可测试性-即获得对组件的受保护访问:
template <class Component>
class System
{
protected:
Component& getComponent(); // for UT only
};并通过推广此功能在UT中允许公共访问:
template <class Component>
class SystemTestable : public System<Component>
{
public:
using System<Component>::getComponent;
};
class SystemTestSuite : public testing::Test
{
protected:
SystemTestable<ComponentMock> objectUnderTest;
};https://stackoverflow.com/questions/41915949
复制相似问题