Git Product home page Git Product logo

hippomocks's Introduction

Hippomocks Build status

Single-header mocking framework.

hippomocks's People

Contributors

baberuth avatar bcachet avatar berkus avatar dascandy avatar denravonska avatar dkgs avatar europar avatar gaillou avatar m00ncheese avatar malveaux avatar martindelille avatar mathiaslte avatar michalkrzyz avatar misery avatar mnhu avatar peterbindels-tomtom avatar rgrymin avatar roysten avatar rzr avatar svitalij avatar tnovotny avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

hippomocks's Issues

noexcep check is incorrect

The ~MockRepository contains a check for noexcept support however that check is incorrect.

if __cplusplus >= 199711L && (!defined(_MSC_VER) || _MSC_VER > 1700)

noexcept(false)

endif

It should be:

if __cplusplus > 199711L || (defined(_MSC_VER) && _MSC_VER > 1700)

noexcept(false)

endif

The VC2015 compiler (and earlier versions) still define __cplusplus as 199711L
So to check for correct VC version, the _MSC_VER has to exist and be larger than 1700 (VC2012)

NotPrintable can be ambiguous with other operator<< overloads

I've a test case for a function with functional argument

#include "hippomocks.h"
#include <functional>

using namespace HippoMocks;

struct A
{
    virtual void f(std::function<void (int)> arg);
};

int main(void)
{
    MockRepository mock;
    A* aptr = mock.Mock<A>();

    mock.ExpectCall(aptr, A::f);

    aptr->f([](int i) {});

    return 0;
}

It worked fine with g++ 4.8.0
g++ -std=c++11 main.cpp // works fine

but printed errors while I compiled it with MS 2010

the error is

C:\Users\Cong\Project\test\test>cl main.cpp
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 16.00.40219.01 for 80x86
Copyright (C) Microsoft Corporation.  All rights reserved.

main.cpp
c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\INCLUDE\xlocale(323) : wa
rning C4530: C++ exception handler used, but unwind semantics are not enabled. S
pecify /EHsc
c:\users\cong\project\test\test\hippomocks.h(466) : error C2593: 'operator <<' i
s ambiguous
        c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\INCLUDE\ostream(2
06): could be 'std::basic_ostream<_Elem,_Traits> &std::basic_ostream<_Elem,_Trai
ts>::operator <<(std::_Bool)'
        with
        [
            _Elem=char,
            _Traits=std::char_traits<char>
        ]
        c:\users\cong\project\test\test\hippomocks.h(441): or       'std::ostrea
m &HippoMocks::operator <<(std::ostream &,const HippoMocks::NotPrintable &)'
        while trying to match the argument list '(std::ostream, std::tr1::functi
on<_Fty>)'
        with
        [
            _Fty=void (int)
        ]
        c:\users\cong\project\test\test\hippomocks.h(463) : while compiling clas
s template member function 'void HippoMocks::printArg<T>::print(std::ostream &,T
,bool)'
        with
        [
            T=std::tr1::function<void (int)>
        ]
        c:\users\cong\project\test\test\hippomocks.h(614) : see reference to cla
ss template instantiation 'HippoMocks::printArg<T>' being compiled
        with
        [
            T=std::tr1::function<void (int)>
        ]
...................

msvc14 causing 'could not deduce template argument'

I am working in a project that uses Hippomocks for c++. Currently we are trying to move to VS2015. somehow between msvc12 and msvc14 i start having compilation errors.

I have the next code on the mock:

    auto myMock = make_shared_mock<IMyInterface>(mocks);
    mocks.ExpectCall(myMock.get(), IMyInterface::Method).With(make_shared<MyParameter>()).Return(make_shared<MyResult>());

And the signature of my Interface is:

struct IMyInterface
{
    virtual ~IMyInterface() = default;
    virtual MyResultPtr Method(const MyParameterPtr& request) const = 0;
        //it has also a variadic template 'Method' and a 'AsyncMethod' definition
};

I am currently getting the error:

Error C2783 'HippoMocks::TCall<Y,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P> &HippoMocks::MockRepository::RegisterExpect_(Z2 *,Y (__stdcall Z::* )(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P) const,HippoMocks::RegistrationType,const char *,const char *,unsigned long)': could not deduce template argument for 'Y'

am I doing something wrong? Is HippoMocks compatible with msvc14?

Tracking a compile warnings when mocking some win32 APIs with MSVC

Hello..

MSVC 2010 - latest hippomock

Mocking some win32 API calls. It works, but I'm getting one of those long winded template warnings:

c:\br\src\unittesting\cppunit\hippomocks.h(464): warning C4800: 'volatile long *' : forcing value to bool 'true' or 'false' (performance warning)
[..]
1> c:\br\src\unittesting\xpaunittests\ipc_client_ut_win32.cpp(68) : see reference to class template instantiation 'HippoMocks::TCall<Y,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P>' being compiled
1> with
1> [
1> Y=LONG,
1> A=volatile LONG *,

The test is basically:

MockRepository mocks;
mocks.OnCallFunc(InterlockedIncrement);

Just curious if there's a way to avoid that warning

Don't manage to mock a Class (only Interface)

The following code crash with message: "Function called without expectation!"

#include <iostream>
using namespace std;
#include "hippomocks.h"
#include "yaffut.h"


class StupidClass { 
public:
  virtual ~StupidClass();
    void c() { cout << "Should never see this method" << endl;}
};

FUNC (check_manageToCallMethod)
{
    MockRepository mocks;
    StupidClass *iamock = mocks.Mock<StupidClass>();
  mocks.ExpectCall(iamock, StupidClass::c);
  iamock->c();
}

If I create an interface, everything works correctly:

class StupidInterface {
public:
  virtual ~StupidInterface () {}
    virtual void c() = 0;
};

class StupidClass : StupidInterface { 
public:
  virtual ~StupidClass() {}
    void c() { cout << "Should never see this method" << endl;}
};

FUNC (check_manageToCallMethod)
{
    MockRepository mocks;
    StupidInterface *iamock = mocks.Mock<StupidInterface>();
  mocks.ExpectCall(iamock, StupidInterface::c);
  iamock->c();
}

I don't understand why do I need to create an interface for every class I want to mock.

Any idea how to solve this issue ?

Sincerely

Bertrand

Exception messages can be much more helpful

The message given by CallMissingException lacks call details. I modified the CallMissingException constructor to mimic that of NoResultSetUpException:

        CallMissingException(MockRepository *repo, const base_tuple *tuple, const char *funcName)
        {
            std::stringstream text;
            text << "Function with expectation not called: ";
            text << funcName;
            if (tuple)
                tuple->printTo(text);
            else
                text << "(...)";
            text << std::endl;
            text << *repo;
            txt = text.str();
        }

Any reason not to use this?

Question: Check calls afterwards?

I like for my test cases to each check a single thing, i.e. contain a single ExpectCall. This means that for moderately complex call chains, I end up with a lot of OnCall specifications to say "ignore these calls on the way to the expectation". If I add a new call in the call chain, I have to update all my existing test cases with a new OnCall ignore spec.

This is quite tedious.

It also prevents me from writing BDD-style tests, where I have a single action in an init method, and then multiple test methods to assert various outcomes.

Would it be possible to set a flag to have HippoMocks accept and record all mock calls, and then be able to do something like:

mocks.ReceivedCall(mock, IInterface::SomeMethod).With(<args>);

Compiling under Microsoft Visual Studio 2010 64-bit

I had to make the changes described below to get my test app building under 64-bit.

Changes submitted for consideration.

Regards
_________________________ diff follows ____________________

diff --git a/HippoMocks/hippomocks.h b/HippoMocks/hippomocks.h
index 8bed15d..cd6db33 100644
--- a/HippoMocks/hippomocks.h
+++ b/HippoMocks/hippomocks.h
@@ -258,6 +258,13 @@ bool operator==( RegistrationType const& rhs, RegistrationType const& lhs )
    return rhs.minimum == lhs.minimum && rhs.maximum == lhs.maximum;
 };

+#if defined(min)
+    #undef  min
+#endif
+
+#if defined(max)
+    #undef  max
+#endif

 const RegistrationType Any = RegistrationType( std::numeric_limits<unsigned>::min(), std::numeric_limits<unsigned>::max() );
 const RegistrationType Never = RegistrationType( std::numeric_limits<unsigned>::min(), std::numeric_limits<unsigned>::min() );
@@ -3560,7 +3567,7 @@ public:
    TCall<Y,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P> &RegisterExpect_(Z2 *mck, Y (Z::*func)(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P) const, RegistrationType expect, const char *funcName, const char *fileName, unsigned long lineNo) { return RegisterExpect_<X>(mck, (Y(Z::*)(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P))(func), expect, funcName ,fileName, lineNo); }
 #endif

-#ifdef _MSC_VER
+#if defined(_MSC_VER) && !defined(_WIN64)
    // COM only support - you can duplicate this for cdecl and fastcall if you want to, but those are not as common as COM.
    template <int X, typename Z2, typename Y, typename Z>
    TCall<Y> &RegisterExpect_(Z2 *mck, Y (__stdcall Z::* func)(), RegistrationType expect, const char *funcName, const char *fileName, unsigned long lineNo);
@@ -4917,7 +4924,7 @@ TCall<void> &MockRepository::RegisterExpectDestructor(Z2 *mck, RegistrationType
    return *call;
 }

-#ifdef _MSC_VER
+#if defined(_MSC_VER) && !defined(_WIN64)
 // Support for COM, see declarations
 template <int X, typename Z2, typename Y, typename Z>
 TCall<Y> &MockRepository::RegisterExpect_(Z2 *mck, Y (__stdcall Z::*func)(), RegistrationType expect, const char *funcName, const char *fileName, unsigned long lineNo)

Improved exception logging

I use Microsoft's unit test framework, and when HippoMocks throws an exception in e.g. VerifyAll, I get a nice stack trace but only "Unhandled C++ exception" as message. Apparently, the test framework doesn't understand standard C++ exceptions and doesn't call what() to get a message.

My current workaround is to have this in hippomocks.h:

#ifdef LOG_EXCEPTION_FUNC
#define LOG_EXCEPTION(x) LOG_EXCEPTION_FUNC(x)
#else
#define LOG_EXCEPTION(x)
#endif

And then modify RAISEEXCEPTION to:

#define RAISEEXCEPTION(e)           { DEBUGBREAK(); LOG_EXCEPTION(e); throw e; }

Would it make sense to have something like that in HippoMocks?

visual studio tests failed in release configuration

With VS2012:
hippomocks\HippoMocksTest\Release>HippoMocksTest_2012.exe
Test checkFunctionReplacedAndChecked failed with exception: a()(1) != 2(2)
Test checkFunctionReturnedToOriginal failed with exception: a()(1) != 2(2)
73 of 75 tests successful

With VS2010:
\hippomocks\HippoMocksTest\Release>HippoMocksTest.exe
Test checkFunctionReplacedAndChecked failed with exception: a()(1) != 2(2)
Test checkFunctionReturnedToOriginal failed with exception: a()(1) != 2(2)
73 of 75 tests successful

in debug configurations are all successful

Unable to return a const ref of an abstract class

There is a compile error with the following test case :

#include "HippoMocks/hippomocks.h"

class B {
public:
   virtual ~B() = 0 {}

   virtual void doSomething() const = 0;

};

class A {
public:
   virtual ~A() = 0 {}

   virtual const B & getB() const = 0;

};

int main(int argc, char * argv[])
{
   MockRepository mocks;

   B * b = mocks.Mock<B>();
   A * a = mocks.Mock<A>();

   mocks.OnCall(a, A::getB).Return(*b);
   mocks.ExpectCall(b, B::doSomething);

   a->getB().doSomething();

   mocks.VerifyAll();
}

It is caused because the ReturnValueHolder does not accept const ref and force the value to be copyable. There is no problem if my methods and return values are non-const.
It seems it is directly related to the comit 72544aa to permit the Return of ref temporay values.

I'm going to see if I can setup a workaround.

dynamic_cast fails on repo.Mock interfaces after casting to a parent type.

If you create a mock object from the repo and cast it to a parent class, you cannot dynamic_cast it back to interface. The mock object is not an implementation of the interface, so it fails the dynamic cast back to the interface type. This code will reproduce the issue in VS2012 32bit & 64bit. Other compilers should also fail.

#include "hippomocks.h"

class IBase
{
    virtual ~IBase();
};

class IInterface : public IBase
{
public:
    virtual ~IInterface();

    virtual void DoWork() = 0;
};


void main()
{
    MockRepository  mockRepo;
    auto pIf = mockRepo.InterfaceMock<IInterface>();

    auto pIBase = dynamic_cast<IBase*>(pIf);
    auto pIf2 = dynamic_cast<IInterface*>(pIBase);  // this will fail due to a lack of RTTI info for IInterface
}

Package HippoMocks for NuGet

Hi,
This is not really an issue. More of a question.
I was wondering if you would be adding this to the new Native NuGet repository?
It would really be handy to be able to just get the latest version as and when you make updates.
Maybe if I get time in the not too distant future I might even take a look at forking and making the required changes to add it there.
Keep up the good work.

Cannot mock standard Win32 Calls in VS2010/2012

I have noticed that some win32 calls are unusable, even when using the actual call (not the macro call). I've tried with the 3.0, 3.1, and last 3 git updated (including the one posted about 7 hours ago)

An example is something as simple as
MockRepository mocks;
mocks.OnCallFunc(GetTickCount); // Same for Sleep/SleepEx, WaitForSingleObject, PostThreadMessageW, DeleteFileW and such.

When you mouse over the "," before OnCallFunc Intellisense reports "Error: no instance of overloaded function "HippoMocks::MockRepository::RegisterExpect_" matches the argument list argument types are: (DWORD (__stdcall *)(), const HippoMocks::RegistrationType, const char[13], const char[71], int) object type is: HippoMocks::MockRepository

When you compile, it throws > 100 errors with the first, and most following similar to:
error C2780: 'HippoMocks::TCall<Y,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P> &HippoMocks::MockRepository::RegisterExpect_(Z2 _,Y (stdcall Z:: )(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P) const,HippoMocks::RegistrationType,const char *,const char *,unsigned long)' : expects 6 arguments - 5 provided
1>
hippomocks.h(3900) : see declaration of 'HippoMocks::MockRepository::RegisterExpect
'

All of the calls I've tried are __stdcall (as expected with win32 calls).
However if we deviate from that and use say _beginthreadex which is __cdecl, it will work, and compile fine.

mocks.OnCallFunc(_beginthreadex).Return(0);

The workaround has been to write a function that calls it like this:
BOOL WP_SetEvent(HANDLE hEvent) { // Using a non-macro'd call
return SetEvent(hEvent);
}

But it would be great if win32 calls did not require them to be wrapped to be mocked.
Great work btw.

cpp11 branch - support for move only types

It would be very useful if functions with move only types such as uinique_ptr could be mocked.

class IFoo {
  virtual void bar( std::unique_ptr<IBar>) = 0:
}

I've tried to see where the problems are. Part of the problem is missing forwarding or moving

  template <int X, typename... Args>
  void expectation(Args... args)
  {
    std::tuple<Args...> argT(std::forward<Args>(args)...); /// <-- added forward here
    mock<Z> *realMock = mock<Z>::getRealThis();
    if (realMock->isZombie)
      RAISEEXCEPTION(ZombieMockException(realMock->repo));
    MockRepository *repo = realMock->repo;
    repo->DoVoidExpectation(realMock, realMock->translateX(X), std::move(argT)); /// <-- added move here
  }

Those can easily be changed. The more problematic issue is with constness.

template <typename Y, typename... Args, int... Nums>
Y _invoke(const std::function<Y(Args...)> &func, seq<Nums...>, const std::tuple<Args...>& args) {
   return func( std::forward<Args>(std::get<Nums>( *const_cast<std::tuple<Args...>*>(&args))...)...); /// <- removed const & forward here
}

With that "hack" the following code compiled.

MockRepository mocks;
auto foo = mocks.Mock<IFoo>();
mocks.ExpectCall(foo, IFoo::bar);

Possible to convert arguments to With?

Sorry for the vague heading but I have something like this:

mocks
    ->ExpectCall(proxyMock, IWebApplicationProxy::ReportProgress)
    .With(L"someid", 0, 3);

This results in a compile-time error with a quite nasty error message:

hippomocks.h(726): error C2536: 'HippoMocks::copy_tuple<A,B,C,HippoMocks::NullType,HippoMocks::NullType,HippoMocks::NullType,HippoMocks::NullType,HippoMocks::NullType,HippoMocks::NullType,HippoMocks::NullType,HippoMocks::NullType,HippoMocks::NullType,HippoMocks::NullType,HippoMocks::NullType,HippoMocks::NullType,HippoMocks::NullType,CA (&),const CB &,const CC &,HippoMocks::NullType,HippoMocks::NullType,HippoMocks::NullType,HippoMocks::NullType,HippoMocks::NullType,HippoMocks::NullType,HippoMocks::NullType,HippoMocks::NullType,HippoMocks::NullType,HippoMocks::NullType,HippoMocks::NullType,HippoMocks::NullType,HippoMocks::NullType>::HippoMocks::copy_tuple<A,B,C,HippoMocks::NullType,HippoMocks::NullType,HippoMocks::NullType,HippoMocks::NullType,HippoMocks::NullType,HippoMocks::NullType,HippoMocks::NullType,HippoMocks::NullType,HippoMocks::NullType,HippoMocks::NullType,HippoMocks::NullType,HippoMocks::NullType,HippoMocks::NullType,CA (&),const CB &,const CC &,HippoMocks::NullType,HippoMocks::NullType,HippoMocks::NullType,HippoMocks::NullType,HippoMocks::NullType,HippoMocks::NullType,HippoMocks::NullType,HippoMocks::NullType,HippoMocks::NullType,HippoMocks::NullType,HippoMocks::NullType,HippoMocks::NullType,HippoMocks::NullType>::a' : cannot specify explicit initializer for arrays

My problem is of course that the error message (1) is hard to decipher and (2) doesn't point to my source code. The reason I see the error is that the ReportProgress takes a wstring as arg 1, so I have to do:

mocks
    ->ExpectCall(proxyMock, IWebApplicationProxy::ReportProgress)
    .With(wstring(L"someid"), 0, 3);

Is it at all possible through template magic to have the compiler realize that it can convert the const wchar_t * to a wstring? Or is it possible to improve the error message?

Compilation error on missing ostream

If an ostream overload doesn't exist for a param type, you get a compilation error on the following code:

if (withComma)
    os << ",";
os << arg;

I ran into this issue when I had to mock a function that had a gsl::not_null param type (from the Guideline Support Library) which doesn't provide an ostream operator. For now I have this commented out..

rethrow copy constructor nothrow bug

If you run clang-tidy against the latest version of hippomocks, you get two errors:

/home/user/hypervisor/include/hippomocks.h:165:25: warning: thrown exception type is not nothrow copy constructible [cert-err60-cpp]
void rethrow() { throw exception; }

/home/user/hypervisor/include/hippomocks.h:4251:10: warning: catch handler catches a pointer value; should throw a non-pointer value and catch by reference instead [cert-err61-cpp]
catch(BASE_EXCEPTION e)

The second one I was able to fix pretty easy, and the error is correct in that, exceptions should be cause by reference (i.e. the code should be BASE_EXCEPTION &e).

The first one however I was not sure how to address. It's complaining that a copy of the exception is being made, and the copy constructor is not marked nothrow. The only thing that came to mind would be to change this code to use a move constructor.

Missing ifdef on when _WIN32 and NO_HIPPOMOCKS_NAMESPACE defined

should the closing curly brace for the namespace on line 196 be inside an ifdef NO_HIPPOMOCKS_NAMESPACE?

current lines:

if defined(_WIN32)

}

// De-windows.h-ified import to avoid including that file.

ifdef _WIN64

extern "C" __declspec(dllimport) int WINCALL VirtualProtect(void *func, unsigned long long byteCount, unsigned long flags, unsigned long *oldFlags);

else

extern "C" __declspec(dllimport) int WINCALL VirtualProtect(void *func, unsigned long byteCount, unsigned long flags, unsigned long *oldFlags);

endif

Should be something like:

if defined(_WIN32)

ifndef NO_HIPPOMOCKS_NAMESPACE

}

endif

// De-windows.h-ified import to avoid including that file.

ifdef _WIN64

extern "C" __declspec(dllimport) int WINCALL VirtualProtect(void *func, unsigned long long byteCount, unsigned long flags, unsigned long *oldFlags);

else

extern "C" __declspec(dllimport) int WINCALL VirtualProtect(void *func, unsigned long byteCount, unsigned long flags, unsigned long *oldFlags);

endif

Document platform support

We also use Linux-on-x86/64, AIX-on-Power and Solaris-on-Sparc platforms at our office and, from reading the HippoMocks headers, it appears that we cannot use HippoMocks as the framework leverages Windows functions like VirtualProtect and has hand-crafted assembly.

Please can you document this somewhere.

No function to undo c-style function hooks

At the moment, it appears that the only way to undo changes to c-style functions is to destroy the MockRepository. The result is I have to do something like this to get the original functionality of a hooked function back:

    do_somthing
    do_somthing

    {
        MockRepository mocks;
        mocks.OnCallFunc(resolve_symbol).Return(-1);

        RUN_UNITTEST_WITH_MOCKS(mocks, [&]
        {
            EXPECT_TRUE(common_dump_vmm() == BF_ERROR_FAILED_TO_DUMP_DR);
        });
    }

    do_somthing
    do_somthing

I was thinking of submitting a PR that moves the destructor code to a function called "doDestroy" that the destructor calls, but could also be called manually if desired. Thoughts?

Version number?

The assembla page from 2009 is version 3.1. What version are we on now? Need one for a manifest:-(

Mocking a function in a shared library gets ignored

I am currently using GCC 5.2 on x86-64. I have a simple test app with a shared library that I am compiling using the same compiler, the only difference is the source is .c (so I have some extern "C" code in the test to link properly).

in the library, I have a simple function:

in foo1(void)
{
    return 10;
}

int foo2(int arg)
{
    return arg + foo1();
}

and in my test code:

MockRepository mocks;
mocks.OnCallFunc(foo1).Return(0);
std::cout << foo2(1) << std::endl;         // returns 11, when it should return 1

Now.... thinking about it for a minute, I added this to the test code

int foo1(void)
{
    return ::foo1()
}

And all of a sudden, the test works fine (i.e. foo2 will return 1). Any ideas? Seems like a bug so I figured I would report it as the documentation doesn't state that you have to override C functions to make this work.

Other than that, I noticed that trying to overload functions like the POSIX "ioctl" and "open" don't play nice with HippoMocks as they have variadic arguments, but I would love to be able to mock these up as well at some point.

Calling an unexpected method on mock crashes on Linux/gcc when return value is an object

class Argument 
{
  public:
    virtual ~Argument() { };
     int value;
 };

class ISS
{
public:
    virtual Argument getValue() = 0;
 };

FUNC(checkUnexpectedCall)
{
MockRepository mocks;

ISS* is = mocks.Mock<ISS>();
bool unexpectedCall = false;

try
{
    Argument arg = is->getValue();
}
catch (HippoMocks::NotImplementedException)
{
    unexpectedCall = true;
}

CHECK(unexpectedCall == true);
}

On a windows /MSVC system this is no issue.

I debugged the scenario and found out, that in case of an object instance as return argument of a function call, there is a "hidden argument" pushed on the stack. So when the call reaches NotImplemented() func the hidden argument is taken as "this" by mistake.
I have no idea, how to fix that properly. The only viable option for me seems to avoid the use of instance data in NotImplentled() at all, directly raising the NotImplemented exception, without tracing the repo data.

Is this an acceptable option? If yes, I would provide a fix for that scenario.

Here's the actual implementation of NotImplemented() function:

void NotImplemented() {
    mock<T> *realMock = getRealThis();
    if (realMock->isZombie)
        RAISEEXCEPTION(ZombieMockException(realMock->repo));
    MockRepository *repository = realMock->repo;
    RAISEEXCEPTION(:: HM_NS NotImplementedException(repository));
}

[feature request] Add support to mock nonvirtual member functions.

I have wrote test example to mock member function to prove It's possible. Can You add more comfortable way to do such mocks? Member functions do not differ very much from free functions, so why not to intercept it the same way? They have __thiscall calling conversion, which can be intercepted exactly by the same "jmp" instruction as common function.

#include "hippomocks.h"

#include <iostream>

class Test
{
public:
  int mem_fun()
  {  return 100; }
};

int main()
{
  MockRepository mocks;

  Test t;
  int(Test::* mem_ptr)() = &Test::mem_fun; // get member function address
  void* mem_fun_ptr = (void*&)mem_ptr;    // convert it to common address
  int (*mem_st)(Test*) = reinterpret_cast<int(*)(Test*)>(mem_fun_ptr);  // convert it to required address type
  mocks.OnCallFuncOverload(mem_st).Return(111);

  std::cout << "Test::mem_fun() " << t.mem_fun() << std::endl;
  return 0;
}

Cant compile test.cpp since 09ecb8fcdfc50603cd266fdbe6b1339aaa56ca37

I've got the following error since the second last commit: 09ecb8f

g++ -std=c++98 -I../HippoMocks/ -Wall -Wextra -pedantic -ansi -g -c -o test.o test.cpp -MMD -MP
In file included from test.cpp:1:
../HippoMocks/hippomocks.h:259: warning: extra ';'
../HippoMocks/hippomocks.h: In constructor 'HippoMocks::Call::Call(HippoMocks::RegistrationType, HippoMocks::base_mock_, const std::pair<int, int>&, int, const char_, const char_)':
../HippoMocks/hippomocks.h:1615: warning: 'HippoMocks::Call::fileName' will be initialized after
../HippoMocks/hippomocks.h:1610: warning: 'unsigned int HippoMocks::Call::called'
../HippoMocks/hippomocks.h:1617: warning: when initialized here
In file included from test.cpp:1:
../HippoMocks/hippomocks.h: In constructor 'HippoMocks::MockRepository::MockRepository()':
../HippoMocks/hippomocks.h:3134: warning: 'HippoMocks::MockRepository::autoExpect' will be initialized after
../HippoMocks/hippomocks.h:3125: warning: 'HippoMocks::ExceptionHolder_ HippoMocks::MockRepository::latentException'
../HippoMocks/hippomocks.h:4049: warning: when initialized here
test.cpp: In constructor '::checkBaseCase::checkBaseCase()':
test.cpp:15: error: 'HippoMocks::Once' cannot appear in a constant-expression
test.cpp:15: error: no matching function for call to 'HippoMocks::MockRepository::RegisterExpect_(IA_&, void (IA::)(), const char [6], const char [9], int)'
test.cpp:16: error: 'HippoMocks::Once' cannot appear in a constant-expression
test.cpp:16: error: no matching function for call to 'HippoMocks::MockRepository::RegisterExpect
(IA_&, void (IA::)(), const char [6], const char [9], int)'
test.cpp: In constructor '::checkMultiCall::checkMultiCall()':
test.cpp:25: error: 'HippoMocks::Once' cannot appear in a constant-expression
test.cpp:25: error: no matching function for call to 'HippoMocks::MockRepository::RegisterExpect
(IA_&, void (IA::)(), const char [6], const char [9], int)'
test.cpp:26: error: 'HippoMocks::Once' cannot appear in a constant-expression
test.cpp:26: error: no matching function for call to 'HippoMocks::MockRepository::RegisterExpect
(IA_&, void (IA::)(), const char [6], const char [9], int)'
test.cpp:27: error: 'HippoMocks::Once' cannot appear in a constant-expression
test.cpp:27: error: no matching function for call to 'HippoMocks::MockRepository::RegisterExpect
(IA_&, void (IA::)(), const char [6], const char [9], int)'
test.cpp: In constructor '::checkMultiCallNotCalled::checkMultiCallNotCalled()':
test.cpp:39: error: 'HippoMocks::Once' cannot appear in a constant-expression
test.cpp:39: error: no matching function for call to 'HippoMocks::MockRepository::RegisterExpect
(IA_&, void (IA::)(), const char [6], const char [9], int)'
test.cpp:40: error: 'HippoMocks::Once' cannot appear in a constant-expression
test.cpp:40: error: no matching function for call to 'HippoMocks::MockRepository::RegisterExpect
(IA_&, void (IA::)(), const char [6], const char [9], int)'
test.cpp:41: error: 'HippoMocks::Once' cannot appear in a constant-expression
test.cpp:41: error: no matching function for call to 'HippoMocks::MockRepository::RegisterExpect
(IA_&, void (IA::)(), const char [6], const char [9], int)'
test.cpp: In constructor '::checkMultiCallWrongOrder::checkMultiCallWrongOrder()':
test.cpp:56: error: 'HippoMocks::Once' cannot appear in a constant-expression
test.cpp:56: error: no matching function for call to 'HippoMocks::MockRepository::RegisterExpect
(IA_&, void (IA::)(), const char [6], const char [9], int)'
test.cpp:57: error: 'HippoMocks::Once' cannot appear in a constant-expression
test.cpp:57: error: no matching function for call to 'HippoMocks::MockRepository::RegisterExpect
(IA_&, void (IA::)(), const char [6], const char [9], int)'
test.cpp:58: error: 'HippoMocks::Once' cannot appear in a constant-expression
test.cpp:58: error: no matching function for call to 'HippoMocks::MockRepository::RegisterExpect
(IA_&, void (IA::)(), const char [6], const char [9], int)'
test.cpp: In constructor '::checkExpectationsNotCompleted::checkExpectationsNotCompleted()':
test.cpp:78: error: 'HippoMocks::Once' cannot appear in a constant-expression
test.cpp:78: error: no matching function for call to 'HippoMocks::MockRepository::RegisterExpect
(IA_&, void (IA::)(), const char [6], const char [9], int)'
test.cpp:79: error: 'HippoMocks::Once' cannot appear in a constant-expression
test.cpp:79: error: no matching function for call to 'HippoMocks::MockRepository::RegisterExpect
(IA_&, void (IA::)(), const char [6], const char [9], int)'
test.cpp: In constructor '::checkOvercompleteExpectations::checkOvercompleteExpectations()':
test.cpp:95: error: 'HippoMocks::Once' cannot appear in a constant-expression
test.cpp:95: error: no matching function for call to 'HippoMocks::MockRepository::RegisterExpect
(IA_&, void (IA::)(), const char [6], const char [9], int)'
test.cpp:96: error: 'HippoMocks::Once' cannot appear in a constant-expression
test.cpp:96: error: no matching function for call to 'HippoMocks::MockRepository::RegisterExpect
(IA_&, void (IA::)(), const char [6], const char [9], int)'
test.cpp: In constructor '::checkExpectationsAreInOrder::checkExpectationsAreInOrder()':
test.cpp:114: error: 'HippoMocks::Once' cannot appear in a constant-expression
test.cpp:114: error: no matching function for call to 'HippoMocks::MockRepository::RegisterExpect
(IA_&, void (IA::)(), const char [6], const char [9], int)'
test.cpp:115: error: 'HippoMocks::Once' cannot appear in a constant-expression
test.cpp:115: error: no matching function for call to 'HippoMocks::MockRepository::RegisterExpect
(IA_&, void (IA::_)(), const char [6], const char [9], int)'
make: *** [test.o] Error 1

My gcc version is 4.4.3

Regards,
David

Cannot see the exception text

I am a bit lost here and cannot find a better place to ask, but how should I make the exception text visible? My program just ends and thats it. I am using GCC from MinGW and compiling with C++11.

ARM 64 bit support

From the code, it looks like it only support ARM 32 bit.
Wondering if it's possible to add ARM 64 bit support?

I am very new to the library, the following code is mysterious to me.
Any reference I can lookup to understand what's going on for ARM 32 bit? Maybe I could apply the similar logic to ARM 64 bit.

    unsigned int *rawptr = (unsigned int *)((intptr_t)(origFunc) & (~3));
    if ((intptr_t)origFunc & 1) {
      rawptr[0] = 0x6800A001;
      rawptr[1] = 0x46874687;
      rawptr[2] = (intptr_t)replacement;
    } else {
      rawptr[0] = 0xE59FF000;
      rawptr[1] = (intptr_t)replacement;
      rawptr[2] = (intptr_t)replacement;

I do see aarch64, however, running the code on an iOS device seems to crash at

rawptr[0] = 0xE59FF000;

DoWrapper stores function as reference

I had the following construct inside a helper function:

mocks
   ->ExpectCall(...)
   .With(...)
   .Do([=](...) { ... });

However, since DoWrapper stores by reference, my lambda function would go out of scope and be destroyed. As a result, captured variables inside the lambda would be corrupt, even if captured by value.

Changing DoWrapper to store by value fixed the problem, but I don't want to hack my HippoMocks header so my current workaround is to create functor instances and store them in a list so that I have control over their lifetime.

Any reason for storing by reference, or is this potentially a bug?

cpp11 branch - turning away from one header philosophy

IMHO one of the unique advantages of hippomocks is the tiny one-header include.

I totally agree, that different classes / aspects should be separated, especially if you want to keep the code clean and maintainable. On the other hand, it's a big advantage having one single file to keep a low barrier and enhance acceptance of non TDD developers.
I would reallly appreciate, to keep the one-header approach, it is especially helpful to setup TDD classes or programming dojos with teams (e.g. on cyber-dojo.org).

cpp11 branch - issues against reporter

This is a collector topic. ( No critic, just my thoughts) ;-)

I had a look at the current implementation and this are my remarks so far:

  1. Provide a proper preprocessor seam, so that defaultreporter can easily be exchanged. I would suggest s.th. like switching the include by a preprocessor keyword. The Reporter injection point in MockRepository constructor is IMHO not enough, because you will have to adapt every single test, or at least every MakeSut() in a suite.
  2. Why do you need TestStarted() and TestFinished(). Isn't this something for a Testrunner framework?
  3. Where is the HM_NO_EXCEPTIONS implementation? No reporting, without exceptions? Is hippo without exceptions a possible use case?
  4. I wonder, if it's feasible to transfer the RAISEEXCEPTION stuff to the testing framework, raising some kind of Testframework::Fail() instead of creating your own exception hierarchy. But I don't know if anybody needs s.th. like: assert_throws(...)
  5. LINUX_TARGET -> duplicate code. Provide a proper seam.

Compile error : cannot use 'throw' with exception disabled

We get this compile error on ExceptionWrapper:rethrow() function in an environment where exceptions are disabled.

Enclosing the following code with #ifndef HM_NO_EXCEPTIONS solves the issue, not sure if this is something that can be taken back?

#ifndef HM_NO_EXCEPTIONS
//Type-safe exception wrapping
class ExceptionHolder
{
public:
    virtual ~ExceptionHolder() {}
    virtual void rethrow() = 0;
    template <typename T>
    static ExceptionHolder *Create(T ex);
};

template <class T>
class ExceptionWrapper : public ExceptionHolder {
    T exception;
public:
    ExceptionWrapper(T ex) : exception(ex) {}
    void rethrow() { throw exception; }
};

template <typename T>
ExceptionHolder *ExceptionHolder::Create(T ex)
{
    return new ExceptionWrapper<T>(ex);
}
#endif

Thanks!

cpp11 branch cannot compile with Visual Studio 2013

Seems to have a lot of different issues inside.
Just 2, I found after a short inspection:

First one: noexcept supported only since VS2015
~MockRepository() // If we're on a recent enough compiler that's not VS2012 (as it doesn't have noexcept) #if __cplusplus > 199711L || (defined(_MSC_VER) && _MSC_VER > 1800) noexcept(false) #endif

Second: I'm not sure, but RegisterExpect seems to resolve to the stdcall overload by default.
May be there's an overload mission for the standard case

Lot's of the testcases don't compile at all.

Detect duplicate __COUNTER__ values

I had a problem whereby some tests would mysteriously fail every now and then, perhaps 1 time out of 20. I mocked a function to return true, but sometimes it would return false instead.

After debugging for a bit, I realized that the problem was that I had some OnCall calls factored out in a separate source file, and since HippoMocks uses __COUNTER__ which is not unique across source files, my mock call actually ended up in a different mocked function (which returned an empty list, which mostly would evaluate to true but sometimes to false, probably depending on memory contents at the time).

My solution was to move all the factored-out OnCall calls to a header instead.

Would it be possible for HippoMocks to detect this situation? What I saw when debugging was that in the following function:

        std::pair<int, int> translateX(int x)
        {
            for (std::map<std::pair<int, int>, int>::iterator i = funcMap.begin(); i != funcMap.end(); ++i)
            {
                if (i->second == x + 1) return i->first;
            }
            return std::pair<int, int>(-1, 0);
        }

...the funcMap list would contain two pairs with the same second value.

Compilation error MSVC 2015

Hello,

I'm trying to use HipoMocks but it seems to be broken on VS2015

class ID {
public:
    virtual ~ID() {};
    virtual int f();
    virtual std::string g() = 0;
};

BOOST_AUTO_TEST_CASE(MyTest)
{
    MockRepository mocks;
    ID *iamock = mocks.Mock<ID>();
    mocks.ExpectCall(iamock, ID::f).Return(1);
    mocks.ExpectCall(iamock, ID::g).Return("fsck");
    BOOST_CHECK(iamock->f() == 1);
    BOOST_CHECK(iamock->g() == "fsck");
}

Error message:

hippomocks.h(1245): error C4700: uninitialized local variable 'conv' used

This is the code:

    if (value != -1)
        return std::pair<int, int>((int)(conv.u.baseoffs/sizeof(void*)), value);

Compilation Error in MSVC2010 with latest h file

I am getting the following error and I am not sure where to start looking to resolve it.

hippomocks.h(694): error C2665: 'HippoMocks::comparer::compare' : none of the 2 overloads could convert all the argument types
4> with
4> [
4> T=const std::basic_string<char,std::char_traits,std::allocator> &
4> ]
4> s:\elateralsvnroot\modules\asp_branches\spikes_33077\33077.elateral.msp.complus.formpresentation\lib\hippomocks\hippomocks\hippomocks.h(508): could be 'bool HippoMocks::comparer::compare(const std::basic_string<_Elem,_Traits,_Ax> &,const std::basic_string<_Elem,_Traits,_Ax> &)'
4> with
4> [
4> T=const std::basic_string<char,std::char_traits,std::allocator> &,
4> _Elem=char,
4> _Traits=std::char_traits,
4> _Ax=std::allocator
4> ]
4> s:\elateralsvnroot\modules\asp_branches\spikes_33077\33077.elateral.msp.complus.formpresentation\lib\hippomocks\hippomocks\hippomocks.h(512): or 'bool HippoMocks::comparer::compare(HippoMocks::DontCare,const std::basic_string<_Elem,_Traits,_Ax> &)'
4> with
4> [
4> T=const std::basic_string<char,std::char_traits,std::allocator> &,
4> _Elem=char,
4> _Traits=std::char_traits,
4> _Ax=std::allocator
4> ]
4> while trying to match the argument list '(const bool, const std::string)'
4> s:\elateralsvnroot\modules\asp_branches\spikes_33077\33077.elateral.msp.complus.formpresentation\lib\hippomocks\hippomocks\hippomocks.h(693) : while compiling class template member function 'bool HippoMocks::copy_tuple<A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,CA,CB,CC,CD,CE,CF,CG,CH,CI,CJ,CK,CL,CM,CN,CO,CP>::operator ==(const HippoMocks::ref_tuple<A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P> &)'
4> with
4> [
4> A=const std::basic_string<char,std::char_traits,std::allocator> &,
4> B=HippoMocks::NullType,
4> C=HippoMocks::NullType,
4> D=HippoMocks::NullType,
4> E=HippoMocks::NullType,
4> F=HippoMocks::NullType,
4> G=HippoMocks::NullType,
4> H=HippoMocks::NullType,
4> I=HippoMocks::NullType,
4> J=HippoMocks::NullType,
4> K=HippoMocks::NullType,
4> L=HippoMocks::NullType,
4> M=HippoMocks::NullType,
4> N=HippoMocks::NullType,
4> O=HippoMocks::NullType,
4> P=HippoMocks::NullType,
4> CA=const bool &,
4> CB=HippoMocks::NullType,
4> CC=HippoMocks::NullType,
4> CD=HippoMocks::NullType,
4> CE=HippoMocks::NullType,
4> CF=HippoMocks::NullType,
4> CG=HippoMocks::NullType,
4> CH=HippoMocks::NullType,
4> CI=HippoMocks::NullType,
4> CJ=HippoMocks::NullType,
4> CK=HippoMocks::NullType,
4> CL=HippoMocks::NullType,
4> CM=HippoMocks::NullType,
4> CN=HippoMocks::NullType,
4> CO=HippoMocks::NullType,
4> CP=HippoMocks::NullType
4> ]
4> s:\elateralsvnroot\modules\asp_branches\spikes_33077\33077.elateral.msp.complus.formpresentation\lib\hippomocks\hippomocks\hippomocks.h(3033) : see reference to class template instantiation 'HippoMocks::copy_tuple<A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,CA,CB,CC,CD,CE,CF,CG,CH,CI,CJ,CK,CL,CM,CN,CO,CP>' being compiled
4> with
4> [
4> A=const std::basic_string<char,std::char_traits,std::allocator> &,
4> B=HippoMocks::NullType,
4> C=HippoMocks::NullType,
4> D=HippoMocks::NullType,
4> E=HippoMocks::NullType,
4> F=HippoMocks::NullType,
4> G=HippoMocks::NullType,
4> H=HippoMocks::NullType,
4> I=HippoMocks::NullType,
4> J=HippoMocks::NullType,
4> K=HippoMocks::NullType,
4> L=HippoMocks::NullType,
4> M=HippoMocks::NullType,
4> N=HippoMocks::NullType,
4> O=HippoMocks::NullType,
4> P=HippoMocks::NullType,
4> CA=const bool &,
4> CB=HippoMocks::NullType,
4> CC=HippoMocks::NullType,
4> CD=HippoMocks::NullType,
4> CE=HippoMocks::NullType,
4> CF=HippoMocks::NullType,
4> CG=HippoMocks::NullType,
4> CH=HippoMocks::NullType,
4> CI=HippoMocks::NullType,
4> CJ=HippoMocks::NullType,
4> CK=HippoMocks::NullType,
4> CL=HippoMocks::NullType,
4> CM=HippoMocks::NullType,
4> CN=HippoMocks::NullType,
4> CO=HippoMocks::NullType,
4> CP=HippoMocks::NullType
4> ]
4> s:\elateralsvnroot\modules\asp_branches\spikes_33077\33077.elateral.msp.complus.formpresentation\elateral.msp.complus.formpresentation.tests\expressionparserfixtures.h(316) : see reference to function template instantiation 'HippoMocks::TCall<Y,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P> &HippoMocks::TCall<Y,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P>::With(const CA &)' being compiled
4> with
4> [
4> Y=void,
4> A=const std::string &,
4> B=HippoMocks::NullType,
4> C=HippoMocks::NullType,
4> D=HippoMocks::NullType,
4> E=HippoMocks::NullType,
4> F=HippoMocks::NullType,
4> G=HippoMocks::NullType,
4> H=HippoMocks::NullType,
4> I=HippoMocks::NullType,
4> J=HippoMocks::NullType,
4> K=HippoMocks::NullType,
4> L=HippoMocks::NullType,
4> M=HippoMocks::NullType,
4> N=HippoMocks::NullType,
4> O=HippoMocks::NullType,
4> P=HippoMocks::NullType,
4> CA=bool
4> ]

Error in RAISEEXCEPTION macro

The definition of the RAISE... macros have an error. The printf call must use c_str() on the err string:

ifdef HM_NO_EXCEPTIONS

define RAISEEXCEPTION(e) { std::string err = e.what(); DEBUGBREAK(e); printf("Mock error found - Fatal due to no exception support:\n"); \

printf("%s\n", err.c_str()); \
abort(); exit(-1); }

Hippomock can crash your tests with ODR violation on Windows

In the hippomocks header the following pragma is defined:

// Tell Microsoft to conform to C++ (as far as is possible...)
#pragma pointers_to_members(full_generality, virtual_inheritance)

If you are not very careful and compile all your code with this setting it can lead to mysterious crashes in your unit tests because you have violated the C++ one definition rule.

I assume that most users are blissfully unaware of this fact, therefore, I strongly recommend this setting be removed and avoid your users long debugging sessions tracking down this problem. It took me a long time to find this problem and I can imagine others not even getting that far.

The awesome thing about fixing this bug is it is not even needed! The pragma is apparently a remnant of an old version and still works without it. Please correct me if I am wrong about that.

In my version of hippomocks from 2010-12-14 (sorry, I'm a little behind) I removed the pragma and it's been working fine (for like 2 years now). I did need to make a small change to get the code to complie without the pragma. I needed to add the " = {}" to the code below:

#elif defined(_MSC_VER)
    union {
        T t;
        struct
        {
            unsigned char *value;
            unsigned long baseoffs;
        } u;
    } conv = {};

Why this is, is a bit of a mystery to me.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.