eranpeer / FakeIt

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

Crashes for unmocked methods with complex return types #85

Open m0ppers opened 7 years ago

m0ppers commented 7 years ago

The following code crashes with a segfault:

#include "catch.hpp"
#include "fakeit.hpp"
#include <string>

using namespace fakeit;

typedef size_t index_t;

struct trans_ret_t {
  bool accepted;
  index_t maxind;
  size_t failed;
  trans_ret_t() : accepted(false), maxind(0), failed(0) {}
};

struct SomeInterface {
  virtual int foo(int) = 0;
  virtual trans_ret_t bar(std::string) = 0;
};

TEST_CASE("test") {
  // Instantiate a mock object.
  Mock<SomeInterface> mock;
  SomeInterface &s = mock.get();
  s.bar("");
}
#0  0x000000000044e685 in fakeit::MockImpl<SomeInterface>::unmocked (this=0x7ffc6d63b980) at 3rdParty/fakeit/fakeit.hpp:18398
18398               auto &fakeit = getMockImpl(this)->_fakeit;
(gdb) bt
#0  0x000000000044e685 in fakeit::MockImpl<SomeInterface>::unmocked (this=0x7ffc6d63b980) at 3rdParty/fakeit/fakeit.hpp:18398
#1  0x0000000000411258 in ____C_A_T_C_H____T_E_S_T____6 () at tests/mufti.cpp:26
#2  0x0000000000418833 in Catch::FreeFunctionTestCase::invoke (this=0x245bf20) at 3rdParty/catch/catch.hpp:7142
#3  0x000000000040a6dd in Catch::TestCase::invoke (this=0x245d130) at 3rdParty/catch/catch.hpp:8086
[...]

Compiled like this:

clang++ -g -O0 -std=c++11 -I3rdParty/catch -I3rdParty/fakeit/ tests/mufti.cpp

g++ crashes as well. Also this crashes on mac as well as on linux.

Removing the bool or the index_t fixes the segfault. I think I hit a bug.

eranpeer commented 7 years ago

It is not a bug. Fakeit will throw an exception (hence the crash) when invoking an un-stubbed method. In order for fakeit to generate a default value it must know the prototype of the method. Standard c++ does not contain any "reflection" mechanism to list the methods of a class, hence you must stub/fake any method you are going to use. The default implementation of an un-stubbed method is to throw an exception. This is the only implementation possible when the return value is unknown.

m0ppers commented 7 years ago

an unmockedexception is of course expected and would be catched by catch here. this is what happens when you remove the bool or index_t in the code.

However as soon as these are included in the code fakeit will not throw such an exception but simply crash :S