Search code examples
multithreadinglambdagoogletestassertgooglemock

Why can't I do an assertion in a GMock `EXPECT_CALL`?


I'm using gtest/gmock-1.12.1 in my project.

I need to do an assertion when a mock method being called, like this:

#include <gmock/gmock.h>
#include <gtest/gtest.h>

using namespace std::placeholders;
using namespace std;
using namespace testing;

struct MyMock_t {
    MOCK_METHOD( bool, isEven, ( int ), ( const ) );
    MOCK_METHOD( void, isNeg, ( int ), ( const ) );
};

int main() {

    MyMock_t moc;

    EXPECT_CALL( moc, isEven( _ ) ).WillRepeatedly( Invoke( []( int i_ )->bool{
        ASSERT_GT( i_, 0 ); // this line can NOT be compiled.
        return i_ % 2 == 0;
    } ) );

    EXPECT_CALL( moc, isNeg( _ ) ).WillRepeatedly( Invoke( []( int i_ ) {
        ASSERT_LT( i_, 0 ); // this line is OK.
    } ) );

    moc.isEven( -3 );
    moc.isNeg( -3 );
};

If the lambad I passed to EXPECT_CALL has a returning type, I can NOT do an ASSERT in it.

It's too trouble to move them outside from the lambda in my real project code(not this exmaple), since there are too assertions need to be done, and EXPECT_CALL is fired in a sub-thread instead of testing main thread(I will have to resolve the thread-sync problem).

How to let them stay in the lambda of EXPECT_CALL?

Compiling Error:

In lambda function:

LambdaAssert.cpp:18:9: error: void value not ignored as it ought to be

18 | ASSERT_GT( i_, 0 );


Solution

  • Either call it in yet another lambda

    []{ ASSERT_GT( i_, 0 ); }();
    

    Or conditionally fail the test

    if ( i_ <= 0 ) ADD_FAILURE() << "Should not happen";
    

    See Assertion Placement for further details.