How to mock a class with both virtual and non-virtual methods using Google Mock?
Asked Answered
F

1

7

I have a class I wish to Mock using Google Mock. My class has BOTH non-virtual and virtual methods. I've been reading through the Google Mock ForDummies and the Google Mock CookBook. The examples and explanations provided by these resources mention classes with either ALL virtual functions, or NO virtual functions, but not one with both. So I have two questions:

(1) Is it possible to mock a class with mixed virtual/non-virtual types?

(2) What method should be used (if question 1 is true) to mock this class, (If question 1 is false) what could be used instead?

A bit of code if it helps:

class Time_Device : public Time_Device_Interface
{   
private:
     ...
     bool read32_irig_data( uint32_t *data_read, uint32_t reg_address);
     bool thread_monitor_irig_changed( irig_callback_t callback );
public:
     ...
     virtual bool set_time( struct time_sample const &time );
     virtual bool get_time( struct time_sample *time );
     virtual bool register_is_connected_notification( 
         irig_callback_t callback );
 };

A wee bit o'background:

I'm trying to use Google Mock with Google Test because I need to mimic hardware returns in a lot of my methods in order to test coverage, etc. I've been able to successfully use Google Test alone to test some of my methods without Mocking them.

I'm developing using Visual Studio 2010, CMake

I'm new to both Google Test and Google Mock

I cannot change the production code.

Felicefelicia answered 1/8, 2014 at 21:32 Comment(2)
What are non-virtual methods doing? If calling virtual methods, then it will make your life difficult.Doucet
@ BЈовић The non-virtual methods do not call virtual methods. They are private methods called by some of the public virtual methods. They are also the methods that access the hardware.Felicefelicia
U
5

(1) Is it possible to mock a class with mixed virtual/non-virtual types?

Yes, it is, but you have to take care. In the mocked class, override only virtual methods.

The mock should look like this :

struct Time_Device_Mock : public Time_Device_Interface
{
    MOCK_CONST_METHOD1( set_time, bool(time_sample const &) );
    MOCK_CONST_METHOD1( get_time, bool(time_sample *) );
    MOCK_CONST_METHOD1( register_is_connected_notification, bool(irig_callback_t) );
};

(2) What method should be used (if question 1 is true) to mock this class, (If question 1 is false) what could be used instead?

This question is a bit weird. You said that non-virtual methods are private, therefore you can not access them. That leaves only option to use virtual methods.

That means, create an instance of the mocked class, and pass it to object which is supposed to use it. The method is called dependency injection, and there are several ways to inject dependency.

Upthrust answered 4/8, 2014 at 15:16 Comment(9)
*Sigh, this is what I was afraid of. Thanks for example. This really came down to bad planning. I'm REALLY rusty with my c++ and I didn't think my testing through and I have created this problem when I could have made it so much easier had I just thought a head more to my testing.Felicefelicia
what you mean by "Yes, it is, but you have to take care."? if all those non-virtual functions are public, then how to mock them?Labiche
@ratzily You can't mock non-virtual methods.Doucet
but it is very normal that a class contains both virtual and non-virtual functions, in this case, it sounds like we can only test with non-virtual functionsLabiche
@ratzily In that case, you can reconsider your design or implementation. It is not possible to override a non-virtual method in a mock class.Doucet
ok, maybe gmock has some drawback, to me, a testing framework should allow developer to mock both virtual and non-virtual easilyLabiche
@ratzily Are you talking about c++? No framework is able to mock non-virtual methods, because that is the way c++ works.Doucet
I mean it is very normal that a class contains both virtual functions and non-virtual functions, there should be a way to mock the non-virtual functhionsLabiche
@Upthrust It's not true that you can't mock non-virtual member functions. It's just not trivial. Function hooking/trampolines can do it. I wrote a poor man's version that does it here: github.com/brandon-kohn/nvmockDid

© 2022 - 2024 — McMap. All rights reserved.