TheProgrammingBatman
TheProgrammingBatman

Reputation: 57

Google Test WillOnce(Return( )) manipulates the expected return-value

I am currently trying to test the capabilities of google test in c++. (To be more specific: google mock)

Now I ran into a problem. It should be super easy, it worked before, but somehow it got messed up and the framework isn't working as expected. Enough talk, here is my problem.

I try to do the simple thing to see if the function "DoSomeMathTurtle" gets invoked once and returns the expected value. But ".WillOnce(Return(x))" manipulates the expected value that it is always true.

class Turtle {
    ...
    virtual int DoSomeMathTurtle(int , int); //Adds two ints together and returns them
    ...
};

My mocking class:

    class MockTurtle : public Turtle{
    public:
        MockTurtle(){
            ON_CALL(*this, DoSomeMathTurtle(_, _))
                .WillByDefault(Invoke(&real_, Turtle::DoSomeMathTurtle)); 
            //I did this so the function gets redirected to a real
            // object so those two numbers actually get added together 
            //(without that it returns always 0)

        }
        MOCK_METHOD2(DoSomeMathTurtle, int(int, int));
    private:
        Turtle real_;
    };

Basic Testing Class:

class TestTurtle : public ::testing::Test{
protected:
    //De- & Constructor
    TestTurtle(){}
    virtual ~TestTurtle(){} //Has to be virtual or all tests will fail

    //Code executed before and after every test
    virtual void SetUp(){}
    virtual void TearDown(){}

    //Test Fixtures which can be used in each test
    MockTurtle m_turtle;
 };

My Testcase:

    TEST_F(TestTurtle, MathTest){
            int x = 2; // Expected value
            int rvalue; // Returned value of the function

            EXPECT_CALL(m_turtle, DoSomeMathTurtle(_, _))
                .Times(1)
                .WillOnce(Return(x));

                rvalue = m_turtle.DoSomeMathTurtle(3,3); // rvalue should be 6 but it is 2
                cout << "[          ] Expected value: " << x << " Returned value " << rvalue << endl;
                //This prints: [          ] Expected value 2 Returned value 2
                //Then the test passes !?
            }
        }

When I comment the "WillOnce(Return(x))" out, rvalue becomes 6 (the value it should become). When "WillOnce(Return(x))" &

ON_CALL(*this, DoSomeMathTurtle(_, _))
                .WillByDefault(Invoke(&real_, Turtle::DoSomeMathTurtle)); 

(in the constructor of my mock-class) is commented out, rvalue becomes 0 (that should also happen).

So as soon as "WillOnce(Return(x))" is in the game, rvalue is always "x".

Thanks in advance for your help! Have a nice, bug-free day!

Upvotes: 2

Views: 17467

Answers (1)

Michał Kalinowski
Michał Kalinowski

Reputation: 189

Mock is all about expectations. When you write in your test:

EXPECT_CALL(m_turtle, DoSomeMathTurtle(_, _))
  .Times(1)
  .WillOnce(Return(x));

You expect that m_turtle will call one time DoSomeMathTurtle that will take any arguments and that will one time return x.

Because x is equal to 2, then when next time when you use m_turtle.DoSomeMathTurtle(any_argument, any_argument); it will return 2.

If you want check arguments,you should look for matchers in googlemock, f.e when you make

EXPECT_CALL(m_turtle, DoSomeMathTurtle(Eq(3), Lt(3)))

you will expect that DoSomeMathTurtle will take two arguments when first is equal to 3 and second is smaller than 3.

If you want get good result in your test you can just write:

EXPECT_CALL(m_turtle, DoSomeMathTurtle(Eq(3), Eq(3)))
  .Times(1)
  .WillOnce(Return(6));
  rvalue = m_turtle.DoSomeMathTurtle(3,3); // rvalue is equal to 6

Upvotes: 1

Related Questions