Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Google mock ByRef method

I have a class that takes a boolean as a reference parameter and returns an integer:

class Foo
{
  public:
    Bar my_bar;
    virtual int myMethod(bool &my_boolean) = 0;
}

/*...*/

int Foo::myMethod(bool &my_boolean){
  if (my_bar == NULL){
    my_boolean = false;
    return -1;
  }
  else{
    my_boolean = true;
    return 0;
  }

}

And I created a mock for this class:

class MockFoo : public Foo
{
   MOCK_METHOD1(myMethod,int(bool &my_boolean));
}

I'm having problems on how to set the expectations for this kind of function,because I need to set the return value and the reference parameter to specific values to properly create my unit tests.How can I deal with this kind of function with gmock?I tried following what I thought was the solution on the documentation:

using ::testing::SetArgPointee;

class MockMutator : public Mutator {
  public:
  MOCK_METHOD2(Mutate, void(bool mutate, int* value));
  ...
};
  ...

MockMutator mutator;
EXPECT_CALL(mutator, Mutate(true, _))
  .WillOnce(SetArgPointee<1>(5));

But either I didn't understood the example or it wasn't applicable for this case.Has anyone dealt whith this kind of situation before?

Thanks in advance.

like image 611
Rodrigo Vasconcelos Avatar asked Jun 21 '13 16:06

Rodrigo Vasconcelos


People also ask

What is SetArgReferee?

SetArgReferee<N>(value) Assign value to the variable referenced by the N -th (0-based) argument. SetArgPointee<N>(value) Assign value to the variable pointed by the N -th (0-based) argument.

What is expect call in Gmock?

In gMock we use the EXPECT_CALL() macro to set an expectation on a mock method. The general syntax is: EXPECT_CALL(mock_object, method(matchers)) . Times(cardinality) .

What is Gmock?

Gmock is a mocking framework for the Groovy language. Gmock is all about simple syntax and readability of your tests so you spend less time learning the framework and more writing code. To use Gmock just drop the gmock jar file in your classpath. The current version is gmock-0.8.


1 Answers

Your question is hard to get! The samples from google mocks 'cook book' are so as well.

Do you want to reuse the implementation for Foo::myMethod() with you mock class, or do you just want to mock the side effects (return value and changed by ref parameters) for specific call situations?

A mock class is usually meant to replace / simulate your Foo class, not to inherit it directly or it's behavior. Don't know if the way you define this 'default' behavior for a pure method will work, but doubt that. You might simply omit the = 0 then. The better approach would be to separate out a real interface declaration like:

struct IFoo
{
    virtual int myMethod(bool &my_boolean) = 0;
    virtual ~IFoo() {}
};

class Foo : public IFoo
{
    // ...
};

class MockFoo : public IFoo
{
   MOCK_METHOD1(myMethod,int(bool &my_boolean));
};

If you have the latter case, you should get off with testing::Return(value) and testing::SetArgReferee<N>(value) (found that in the very useful 'Cheat Sheet').

Your expectation call should look like this then:

MockFoo foo;

// Expect call to myMethod() return -1 and set the by ref argument to true
EXPECT_CALL(foo, myMethod(_))
  .WillOnce(DoAll(SetArgReferee<0>(true),Return(-1)));

// Expect call to myMethod() return 0 and set the by ref argument to false
EXPECT_CALL(foo, myMethod(_))
  .WillOnce(DoAll(SetArgReferee<0>(false),Return(0)));

If you really want to reuse your original classes logic for myMethod() have a look at 'Delegating calls to a parent class', resp. 'Delegating Calls to a Real Object'

like image 128
πάντα ῥεῖ Avatar answered Sep 22 '22 16:09

πάντα ῥεῖ