Search code examples
c++googletestgooglemock

google mock - save EXPECT_CALL then re-use and change clauses


Let's say you have this:

EXPECT_CALL(MockClass_obj, f1(55)).Times(1);
// use the expectation
// ...

// Now clear it
Mock::VerifyAndClear(&MockClass_obj)

Is it possible to 1) Save the expectation
AND
2) Re-use it later and change the clauses?

From here I know it's possible to save expectations but there's nowhere else that expounds on what else can be done.

Referring to the above code, I want to do something like:

Expecatation exp1 = EXPECT_CALL(MockClass_obj, f1(55)).Times(1);
// use the expectation
// ...

// Now clear it
Mock::VerifyAndClear(&MockClass_obj)

// Somehow modify exp1 to change the cardinality or any of the clauses  
// so that I can make the test immediately readable and convey that it's very much related to the one above":

// Instead of this:
EXPECT_CALL(MockClass_obj, f1(55)).Times(0);

// I wanna do something like
exp1.Times(0)

Solution

  • No, it is not possible in the way described in question. The Expectation class is just to be used in After clause and nothing else - by google-mock design you cannot do anything else with it.

    But, with proper encapsulation - you might achieve the goal, like:

    ::testing::Expectation expectF1For55(::testing::Cardinality cardinality)
    {
        EXPECT_CALL(MockClass_obj, f1(55)).Times(cardinality);
    }
    

    And use:

    auto exp1 = expectF1For55(Exactly(1));
    // ...
    
    // ...
    expectF1For55(Exactly(0));
    

    However I bet, the question is more general than just to cover this very example.

    E.g. you can encapsulate entire Expectation - whatever you need - like:

    class F1Expectation
    {
    public:
        F1Expectation(MockClass&);
        Expectation expect(int arg, ::testing::Cardinality cardinality = Exaclty(1))
        {
           m_arg = arg;
           return EXPECT_CALL(obj, f1(m_arg)).Times(cardinality);
        }
        Expectation expect(::testing::Cardinality cardinality)
        {
           return EXPECT_CALL(obj, f1(55)).Times(cardinality);
        }
    private:
        MockClass& obj;
        Matcher<int> m_arg = _;
    };
    

    And use:

    F1Expectation exp1(MockClass_obj);
    exp1.expect(1);
    // ...
    
    // ...
    exp1.expect(0);