Search code examples
c++googlemock

mock a function which has double pointer as argument


Mock a method which has raw double pointer, for example below class Helper has a method int run(int** a). I am trying to set expectations using SetArgPointee, but it is not working. giving compiler error can not convert int** const to int*.

  class Helper {
  public:
       MOCK_METHOD1(run, int(int ** a));
   };

    int** test = new int*[2];

    test[0] = new int[1];
    test[0][0] = 5;

    test[1] = new int[1];
    test[1][0] = 55;

    int** test2 = new int*[2];

    test2[0] = new int[1];
    test2[0][0] = 10;

    test2[1] = new int[1];
    test2[1][0] = 110;

    Helper helper;
    EXPECT_CALL(helper, run(_))
        .Times(1)
        .WillOnce(DoAll(SetArgPointee<0>(test2), Return(99)));

    int rc = helper.run(test);

I am not able to replace test double pointer with test2. want to know how it can be done.


Solution

  • This is not a complete answer but I will post it, because it is too long for a comment.

    First of all, you should probably explain what are you trying to achieve, because usually there is no justification for setting the called mock function arguments (at least, if you do not plan to do anything else with modified arg).

    SetArgPointee only allows you to set the value at a[0], because this the memory your pointer is pointing at:

    int** mockInput1 = new int*[2];
    int** mockInput2 = new int*[2];
    EXPECT_CALL(helper, run(_))
        .Times(1)
        // this will set value pointed by mockInput2[0] to mockInput1[0]
        .WillOnce(DoAll(SetArgPointee<0>(mockInput1[0]), Return(99)));
    helper.run(mockInput2);
    

    However, I am almost sure that this not what you are looking for. Note that gmock allows you to define custom actions that can be invoked after your call is matched:

    auto action = [](int** a) {
        int** test = new int*[2];
        test[0] = new int[1];
        test[0][0] = 5;
        test[1] = new int[1];
        test[1][0] = 55;
        a[0] = test[0];
        a[1] = test[1];  // or whatever
        std::cout << "Executed custom action" << std::endl;
    };
    EXPECT_CALL(helper, run(_))
        .Times(1)
        .WillOnce(DoAll(Invoke(action), Return(99)));
    helper.run(mockInput2);
    

    Inside the action you can do whatever you want. Anyway, try to explain what do you actually try to achieve.

    Also, please not the memory leaks possibility if you do not delete your memory appropriately.