Search code examples
c++googletestgooglemock

Is there a way in gmock to return modified input arg without invoke?


I want to do something like this:

EXPECT_CALL(*mock, method(5)).WillOnce(Return(arg1 * 2));

where arg1 should be equal to first arg of called method. Is there a way to do that without testing::Invoke?


Solution

  • Method 1:

    You can use a custom matcher, as the other answer mentioned, however, notice that the preferred way of using custom matchers is by using functors, not the ACTION macro (See here).

    Here is an example:

    // Define a functor first:
    struct Double {
      template <typename T>
      T operator()(T arg) {
        return 2 * (arg);
      }
    };
    
    
    TEST(MyTest, CanDoubleWithFunctor) {
      MyMock mock;
    
      // Use the functor in the test:
      EXPECT_CALL(mock, method(5)).WillOnce(Double{});
    
      EXPECT_EQ(mock.method(5), 10);
    }
    
    

    See a working example here: https://godbolt.org/z/h4aaPdWMs


    Method 2:

    Besides the custom matcher, you can use WithArg see here, and pass the first argument to it, which will then be passed to a function that takes one argument. This function can be standalone, or a lambda function:

    class MyMock {
     public:
      MOCK_METHOD(int, method, (int), ());
    };
    
    TEST(MyTest, CanDouble) {
      MyMock mock;
    
      EXPECT_CALL(mock, method(5)).WillOnce(WithArg<0>([](int x) {
        return x * 2;
      }));
    
      EXPECT_EQ(mock.method(5), 10);
    }
    
    

    See this working example.