web-dev-qa-db-ja.com

gmockのsaveArgとsaveArgPointeeの違いは何ですか?

私はgmockで勉強しています。今、私は次のように「タスク」という名前のクラスをモックしようとしています。

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

そして、task.excuteが呼び出されたときにstruct pdataを保存して、pdata-> memberを検証できるようにします。これは私のコードです:

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

あれは正しいですか?そして、saveArgとsaveArgPointeeの違いは何ですか?

7
XHLin

あなたが読むことができるように gmock doc

SaveArg(pointer)N番目(0ベース)の引数を* pointerに保存します。

SaveArgPointee(pointer)N番目(0ベース)の引数が指す値を* pointerに保存します。

あなたの場合、あなたはSaveArgPointeeを使うべきです-あなたは指摘されたデータを保存したいので(PACKET_DATA *Data)-ポインタ自体ではありません。

この例を見てください:

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

someFunctionをテストするには、fooに渡されているポインティを確認する必要があります。

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

SaveArgを使用した場合、存在しなくなったローカル変数へのポインタを格納するだけです。

TEST(TestSomeFoo, shallPassOne_DanglingPointer)
{
    SomeData* actualData;
    SomeMock aMock;
    EXPECT_CALL(aMock, foo(_)).WillOnce(::testing::SaveArg<0>(&actualData));
    someFunction(aMock);
    ASSERT_EQ(1, actualData->a);
}
10
PiotrNycz
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);
}

これは同じですか、それとも違いがありますか?

1
Akshat