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;
}
要测试此行如何准确设置模拟?
Children
是 vector
个节点,我们正在传递模拟对象。
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);
}
请考虑以下代码示例
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
个节点,我们正在传递模拟对象。
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);
}