eranpeer / FakeIt

C++ mocking made easy. A simple yet very expressive, headers only library for c++ mocking.
MIT License
1.24k stars 173 forks source link

Crash with a mocked class having a virtual destructor #162

Open AlexianMasson opened 5 years ago

AlexianMasson commented 5 years ago

Hi,

one of my google test suite, that use for the first time the fakeit::Mock feature, had crashed but ONLY on a Windows 10 Win32 RELEASE build.

On Debug it works and on MacOs/Ubuntu system it works also but on Debug AND Release mode (using clang, didn't try with gcc).

I identify the problem but didn't understand it : The test suite crash when the mocked class have a virtual destructor.

Here is a minimalist example that crash on Windows 10 with Win32 on Release mode:

main.cpp

#include <gtest/gtest.h>

#include <QCoreApplication>

int main(int argc, char** argv)
{
    new QCoreApplication(argc, argv);
    ::testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
}

A.h

class A
{
public:
    A() = default;
    virtual ~A() = default;

    virtual void foo() {}
};

MockTest.h

#include <gtest/gtest.h>
#include <fakeit.hpp>

#include "A.h"

class MockTest : public ::testing::Test
{
private:
    fakeit::Mock< A > aMock;
};

MockTest.cpp

#include "MockTest.h"

TEST_F(MockTest, Given_When_Then)
{
    ASSERT_EQ(true, true);
}

Solution to make the test suite works: Remove the virtual destructor...

ericlemes commented 5 years ago

Hey @alaenix,

FakeIt relies on internal compiler implementation. I don't think working in Release is expected. I found that even changing the level of debug information causes destructor mocks to fail. I'm not sure if this is your case.

I added this in the readme, after some similar issues:

"In MSC++, your project must have Edit And Continue debug mode on (https://msdn.microsoft.com/en-us/library/esaeyddf.aspx) which is same of /ZI compiler switch. If you don't use this, you will have exceptions mocking destructors (which includes unique_ptr and other smart pointers)."

AlexianMasson commented 5 years ago

Hi @ericlemes,

thanks for your response.

FakeIt relies on internal compiler implementation. I don't think working in Release is expected.

In my case, I used a CI system to build and test an application. To be close to user usage of the application, this tests are run on Release mode.

I found that even changing the level of debug information causes destructor mocks to fail. I'm not sure if this is your case.

I've seen this issue but i don't think this is my case.

I found a workaround by not using virtual destructor but I will eventually investigate the usage of WinGW on Release.

helmesjo commented 5 years ago

@eranpeer Regarding "Release mode", are there any limitations to expect with FakeIt?

acsvln commented 5 years ago

Have same problem under GCC 5.4.0. CLang 4.0 works well

paraka commented 5 years ago

Same problem found using gcc 8.3.0 compiling for x86_64 for qemu using yocto.

The problem is workarounded compiling with -O0.