c++ - gmock gtest 如何设置模拟

标签 c++ unit-testing googletest googlemock

请考虑以下代码示例

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

要测试此行如何准确设置模拟? Children 是节点的 vector,我们正在传递 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());

最佳答案

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

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

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

关于c++ - gmock gtest 如何设置模拟,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39004952/

相关文章:

c++ - 删除外部类实例中的内部类实例

sql - 我应该如何执行 SQL ETL 脚本和 SPROC 的自动化测试?

c++ - 针对具有 gtest 程序的以下情况进行设计

unit-testing - 使用枚举的 CakePHP 测试的解决方法?

javascript - 如何禁用单行的 Flow (JS) 类型检查

c++ - 如何在谷歌测试中强制正确的预期和实际顺序?

c++ - 在 gtest 中比较 ptr 和 nullptr

c++ - OpenCV 2.4 : undefined reference to cvRand

c++ - 在 Linux 中使用 C/C++ 强制 tcp/ip 跟踪路由经过特定跃点

c++ - 将二维数组映射到 Eigen::Matrix