简体   繁体   中英

What is the difference of saveArg and saveArgPointee in gmock?

I am studying in the gmock. Now Im trying to mock the class named "task", like this:

class MockTask : public Task
{
public:
    MOCK_METHOD3(Execute, bool(std::set<std::string> &setDeviceIDs, int timeout, PACKET_DATA *Data));
};

And I want to save the struct pdata when the task.excute is called, so that I can validate the pdata->member. This is my code:

PAKET_DATA data;
EXPECT_CALL(task, Execute(testing::_, testing::_, testing::_))
    .WillOnce(testing::saveArg<2>(&data));
ASSERT_EQ(data->resultcode, 0);

Is that correct? And what is the difference of saveArg and saveArgPointee?

As you can read in gmock doc :

SaveArg(pointer) Save the N-th (0-based) argument to *pointer.

SaveArgPointee(pointer) Save the value pointed to by the N-th (0-based) argument to *pointer.

for your case, you should use SaveArgPointee - as you want to save pointed data ( PACKET_DATA *Data ) - not the pointer itself...

Look at this example:

struct SomeData { int a; };
class ISomeClass
{
public:
    virtual ~ISomeClass() = default;
    virtual void foo(SomeData*) = 0;
};

void someFunction(ISomeClass& a)
{
    SomeData b{1};
    a.foo(&b);
}

class SomeMock : public ISomeClass
{
public:
    MOCK_METHOD1(foo, void(SomeData*));
};

To test someFunction you need to check pointee that is being passed to foo :

TEST(TestSomeFoo, shallPassOne)
{
    SomeData actualData{};
    SomeMock aMock;
    EXPECT_CALL(aMock, foo(_)).WillOnce(::testing::SaveArgPointee<0>(&actualData));
    someFunction(aMock);
    ASSERT_EQ(1, actualData.a);
}

If you used SaveArg - you would just store pointer to local variable that no longer exists:

TEST(TestSomeFoo, shallPassOne_DanglingPointer)
{
    SomeData* actualData;
    SomeMock aMock;
    EXPECT_CALL(aMock, foo(_)).WillOnce(::testing::SaveArg<0>(&actualData));
    someFunction(aMock);
    ASSERT_EQ(1, actualData->a);
}
If I replace the test 
TEST(TestSomeFoo, shallPassOne)
{
    SomeData actualData{};
    SomeMock aMock;
    EXPECT_CALL(aMock, foo(_)).WillOnce(::testing::SaveArgPointee<0>(&actualData));
    someFunction(aMock);
    ASSERT_EQ(1, actualData.a);
}

as 

TEST(TestSomeFoo, shallPassOne)
{
    SomeData actualData{1};
    SomeMock aMock;
    EXPECT_CALL(aMock, foo(actualData)).Times(1);
    someFunction(aMock);
}

Will this be same or makes any difference?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM