Google Mock: Can I use global layouts?

In all gmock documentation, I always find that a mock object is created inside the test, for example:

TEST(Bim, Bam) { MyMockClass myMockObj; EXPECT_CALL(MyMockObj, foo(_)); ... } 

Thus, an object is created and destroyed for each test. I find it also ideal for creating and destroying an object on every test equipment. But I am wondering if it is ok to have a file-global instance of the mock object, for example:

 MyMockClass myMockObj; TEST(Bim, Bam) { EXPECT_CALL(MyMockObj, foo(_)) ... } 

I tried, and I have no problems so far, everything seems to be working fine. But maybe I should know about something? Just because I stumbled upon this question where the only answer says:

... the problem is that you are creating a global instance of FooMock. Googlemock / googletest expects the layout to be defined both inside the test body and in the class of the device under test.

But I could not find anything in the documentation or anywhere else that confirms this (I did not miss it?).

Thanks Georg

PS: The reason I need to use the global mock instance will be the subject of another discussion (see this post ).

+4
source share
3 answers

You can, but it's not a good idea.

Doing such a thing violates the UT isolation principle. This violation may lead to an unexpected failure / skip in your tests.

Gtest uses a fake object destructor to verify that an expectation has occurred, which is the reason that each fake object will be created and released in the test body or in the test device class.

If you create a fake global object, it will not be released at the end of each UT , then the check will fail and the test will pass even if it should fail. more than some of your UTs may have fass / fail when running all your tests together; in one test, you expect method x not call, and in another you expect the method to call; in one UT, you expect method x to call 3 times, but the method was called twice in the test + one in the other test (the test should fail, but it will not ...)

So, on the bottom line, you should never use a global mock unless this global layout is used only to prevent a null pointer (you haven't set a behavior ..)

+3
source

Just stumbled upon this question, pursuing a mistake related to my dummy objects. In my case, the problem was that the dummy object constructor was called before InitGoogleMock , and that seemed to InitGoogleMock things to the weeds.

Note. I am using Google Mock with CppUnitTestFramework.

Failure:

 MockObject mock; TEST_MODULE_INITIALIZE(ModuleInitialize) { InitGoogleMock(argc, argv); } 

Win:

 MockObject *mock = nullptr; TEST_MODULE_INITIALIZE(ModuleInitialize) { InitGoogleMock(argc, argv); mock = new MockObject; } TEST_MODULE_CLEANUP(ModuleCleanup) { delete mock; } 

I'm not saying this is best practice or something like that, but if you need global dummy objects, I would say pay attention to when your constructors are called.

+1
source

In addition to the accepted answer, if you use GTest, global variables will also be marked as leaks if they are not destroyed after running the test cases. The idea of ​​the leak is this: https://github.com/google/googletest/blob/master/googlemock/docs/CookBook.md#forcing-a-verification

If you do not want to check manually, the closest solution would be to use a dummy object as a member of your instrument class. And if for some reason you need to dynamically distribute the layout, you can have a pointer and create / destroy an instance in SetUp and TearDown (the same concept as in @Chris Olsen's answer). Or, if you are in C ++ 11, you can use shared_ptr:

 class Fixture : public ::testing::Test { std::shared_ptr<ObjT> mPtr; ... void SetUp() { mPtr = std::make_shared<ObjT>(); } ... } 
0
source

All Articles