gmock gtest 如何设置模拟

gmock gtest how to setup the mock

请考虑以下代码示例

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 个节点,我们正在传递模拟对象。

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

并且 GetANewNode 将提供新的 MockedNode

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

如何为每个 Next()Previous() 调用提供准确的节点?[​​=18=]

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

简单的解决方案是在测试用例之前预定义所有模拟节点。并使用 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);
   }
};

通过初始设置进行此类测试 class - 您可以创建测试用例来测试初始序列后发生的各种场景:

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...
}

两个非常相似的测试用例children:

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);
}