googletest
googletest copied to clipboard
Mock object leaks after EXPECT_CALL and EXPECT_EXIT with -1
Describe the bug
After I call EXPECT_CALL on a mock object and then call a function that returns -1 from EXPECT_EXIT I get a message about an object that should be deleted but never being:
somefile.cpp:198: ERROR: this mock object (used in test TestDummy.dummy_test) should be deleted but never is. Its address is @0x22c8c60.
ERROR: 1 leaked mock object found at program exit. Expectations on a mock object are verified when the object is destructed. Leaking a mock means that its expectations aren't verified, which is usually a test bug. If you really intend to leak a mock, you can suppress this error using testing::Mock::AllowLeak(mock_object), or you may use a fake or stub instead of a mock.
Steps to reproduce the bug
Following is a MRE:
class Dummy
{
public:
virtual ~Dummy() = default;
virtual bool bar() = 0;
};
class DummyMock : public Dummy
{
public:
~DummyMock()
{
std::cout << "something" << std::endl;
}
MOCK_METHOD(bool, bar, (),(override));
};
class TestDummy : public testing::Test
{
protected:
TestDummy()
: mock(DummyMock())
{
}
DummyMock mock;
};
int foo()
{
exit(1);
}
TEST_F(TestDummy, dummy_test)
{
EXPECT_CALL(mock, bar()).Times(1).WillOnce(Return(true));
EXPECT_EXIT(foo(), testing::ExitedWithCode(1), "");
}
Does the bug persist in the most recent commit?
This is the latest release 1.11
What operating system and version are you using?
Centos 7:
Linux <hostname> 3.10.0-1062.12.1.rt56.1042.el7.x86_64 #1 SMP PREEMPT RT Wed Feb 5 10:31:05 CET 2020 x86_64 x86_64 x86_64 GNU/Linux
What compiler and version are you using?
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/opt/rh/devtoolset-8/root/usr/libexec/gcc/x86_64-redhat-linux/8/lto-wrapper
Target: x86_64-redhat-linux
Configured with: ../configure --enable-bootstrap --enable-languages=c,c++,fortran,lto --prefix=/opt/rh/devtoolset-8/root/usr --mandir=/opt/rh/devtoolset-8/root/usr/share/man --infodir=/opt/rh/devtoolset-8/root/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-shared --enable-threads=posix --enable-checking=release --enable-multilib --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --with-gcc-major-version-only --with-linker-hash-style=gnu --with-default-libstdcxx-abi=gcc4-compatible --enable-plugin --enable-initfini-array --with-isl=/builddir/build/BUILD/gcc-8.3.1-20190311/obj-x86_64-redhat-linux/isl-install --disable-libmpx --enable-gnu-indirect-function --with-tune=generic --with-arch_32=x86-64 --build=x86_64-redhat-linux
Thread model: posix
gcc version 8.3.1 20190311 (Red Hat 8.3.1-3) (GCC)
What build system are you using?
cmake3 version 3.17.5
Thanks for the detailed bug report.
This is most likely caused by the interaction of things:
- When defining the EXPECT_CALL on a mock object, GoogleTest adds it to an internal collection of mock objects
- EXPECT_DEATH creates a subprocess that exits abruptly
I believe the subprocess does not get to clean up the collection of mock objects, which is why we are seeing this.
To mitigate the issue, you could either swap the order of EXPECT_DEATH and EXPECT_CALL or separate the EXPECT_DEATH into its own test case.
Would either of those work?
I just checked and swapping them does not solve the issue. Also, separating the EXPECT_DEATH is probably not possible as our object under test calls mock's functions in its constructor so we will be having some expects on it anyway.
Hi, if you want to get rid of the error message you can try Mock::AllowLeak(&mock); right before your EXPECT_EXIT call. This will suppress the error message (worked for me with version 1.12.1).
As the death test is executed in a subprocess, you need to put your EXPECT_CALL into EXPECT_EXIT, such as TEST_F(TestDummy, dummy_test) { EXPECT_EXIT( EXPECT_CALL(mock, bar()).Times(1).WillOnce(Return(true));foo(), testing::ExitedWithCode(1), ""); }