GMOCK - how to modify the method arguments when return type is void
Asked Answered
W

1

5

I have a class which accepts a pointer to another class and has a method read():

class B:
{
public:
......
void read(char * str);
......
};

class A
{
public:
A(B *bobj):b(bobj);
B* b;
void read (char * str);
..........
};

I invoke the object like below

A * aobj = new A(new B());

Now I should be able to access read method of both the classes like below:

char text[100];
b->read(text)
aobj->read(text)

The method read of both A and B class is coded to copy some values to the input array as provided.

How can I write MOCK method of the function to modify the argument to a specific value?

ON_CALL(*b, read(::testing::_)).WillByDefault(::testing::Return(outBuffer));

Gives me a compilation issue as read method cannot return a value by definition?

Wot answered 7/9, 2017 at 9:28 Comment(0)
M
8

I have used Invoke function to achieve this. Here is a sample code.

If you use >=c++11 then, you can simply give a lambda to the Invoke function.

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

using ::testing::Mock;
using ::testing::_;
using ::testing::Invoke;

class actual_reader
{
   public:
   virtual void read(char* data)
   {   
      std::cout << "This should not be called" << std::endl;
   }   
};
void mock_read_function(char* str)
{
   strcpy(str, "Mocked text");
}

class class_under_test
{
   public:
      void read(actual_reader* obj, char *str)
      {   
         obj->read(str);
      }   
};

class mock_reader : public actual_reader
{
   public:
   MOCK_METHOD1(read, void(char* str));
};


TEST(test_class_under_test, test_read)
{
   char text[100];

   mock_reader mock_obj;
   class_under_test cut;

   EXPECT_CALL(mock_obj, read(_)).WillOnce(Invoke(mock_read_function));
   cut.read(&mock_obj, text);
   std::cout << "Output : " << text << std::endl;

   // Lambda example
   EXPECT_CALL(mock_obj, read(_)).WillOnce(Invoke(
            [=](char* str){
               strcpy(str, "Mocked text(lambda)");
            }));
   cut.read(&mock_obj, text);
   std::cout << "Output : " << text << std::endl;



}
Mahatma answered 7/9, 2017 at 10:27 Comment(4)
Thanks - can you please provide lambda function since I am using C++11Wot
Should be simple, I will add itMahatma
Thanks - is it also possible to pass a user defied arguments along with actual one - something like - Invoke(mock_read_function(_, "This is a test")) where _ is the actual argument called and next one is user defined with could be int, array etc in this case it is an stringWot
No. The signature of the mock_read_function should be same as that of the read function that you want to mock.Mahatma

© 2022 - 2024 — McMap. All rights reserved.