gmock gtest如何设置模拟

时间:2016-08-17 19:38:31

标签: c++ unit-testing googletest googlemock gmock

请考虑以下代码示例

NodeInterface * pPreNode = NULL;
NodeInterface * pChild = NULL;

for (uint16_t Index = 0; Index < Children.size(); ++Index)
{
    pChild = Children[Index];
    if (pPreNode == NULL)
    {
        pChild->SetPrevious(pChild);
        pChild->SetNext(pChild);
    }
    else
    {
        pChild->SetNext(pPreNode->GetNext());
        pChild->SetPrevious(pPreNode);
        pPreNode->GetNext()->SetPrevious(pChild);
        pPreNode->SetNext(pChild);
    }
    pPreNode = pChild;
}

要测试此行,如何准确设置模拟? Childrenvector个节点,我们正在传递Mocked对象。

EXPECT_CALL(Obj, GetNode()).WillOnce(Invoke(this, &GetANewNode));

并且GetANewNode将提供新的MockedNode

MockedNode * GetANewNode()
{
    MockedNode * pMockedNode = new MockedNode();
    return pMockedNode;
}

如何为每个Next()Previous()来电提供确切的节点?

EXPECT_CALL(*pMockedNode, SetNext(_));
EXPECT_CALL(*pMockedNode, SetPrevious(_));
EXPECT_CALL(*pMockedNode, GetNext());
EXPECT_CALL(*pMockedNode, GetPrevious());

1 个答案:

答案 0 :(得分:2)

简单的解决方案是在测试用例之前预先定义所有模拟节点。并使用Sequence / InSequence确保一切按正确顺序发生。

class ObjTest : public ::testing::Test
{
protected:
   const std::size_t N = ...; // I do not know how many do you need
   std::vector<MockedNode> mockedNode;
   std::vector<Node*> children; 
   Sequence s;
   .... Obj; // I am not sure what is Obj in your question
   ObjTest () : mockedNode(N)
   {}
   void SetUp() override
   {
       // initial setup
       EXPECT_CALL(Obj, GetNode()).WillOnce(Return(&mockedNode.front())).InSequence(s);
   }
};

拥有初始设置的测试类 - 您可以创建测试用例,测试在初始序列之后发生的各种场景:

TEST_F(ObjTest, shouldLinkOneNodeToItself)
{
    std::vector<Node*> children { &mockedNode[0] };
    EXPECT_CALL(mockedNode[0], SetNext(&mockedNode[0])).InSequence(s);
    EXPECT_CALL(mockedNode[0], SetPrevious(&mockedNode[0])).InSequence(s);
    Obj.testedFunction(children); // you have not provided your tested function name...
}

两个孩子的测试案例非常相似:

TEST_F(ObjTest, shouldLinkTwoNodesToEachOther)
{
    std::vector<Node*> children { &mockedNode[0], &&mockedNode[1] };
    // first interation
    EXPECT_CALL(mockedNode[0], SetNext(&mockedNode[0])).InSequence(s);
    EXPECT_CALL(mockedNode[0], SetPrevious(&mockedNode[0])).InSequence(s);
    // second iteration
    EXPECT_CALL(mockedNode[0], GetNext()).WillOnce(Return(&mockedNode[0])).InSequence(s);
    EXPECT_CALL(mockedNode[1], SetNext(&mockedNode[0])).InSequence(s);
    EXPECT_CALL(mockedNode[1], SetPrevious(&mockedNode[0])).InSequence(s);
    // etc...

    Obj.testedFunction(children);
}