Single-header mocking framework.
dascandy / hippomocks Goto Github PK
View Code? Open in Web Editor NEWLicense: GNU Lesser General Public License v2.1
License: GNU Lesser General Public License v2.1
The ~MockRepository contains a check for noexcept support however that check is incorrect.
noexcept(false)
It should be:
noexcept(false)
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)
I investigated the problem and found a solution (including some new tests).
I would like to contribute to the project.
Would please someone give me a hint how?
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)>
]
...................
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?
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
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
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?
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>);
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)
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?
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
GCC ABI compilers work, but MSVC is not implemented yet.
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.
Tracked down, its the unitialized union in virtual_index function:
#elif defined(_MSC_VER)
union {
T t;
struct
{
unsigned char *value;
unsigned long baseoffs;
} u;
} conv;
should be conv = {};
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
}
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.
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.
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);
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?
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..
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.
should the closing curly brace for the namespace on line 196 be inside an ifdef NO_HIPPOMOCKS_NAMESPACE?
current lines:
}
// De-windows.h-ified import to avoid including that file.
extern "C" __declspec(dllimport) int WINCALL VirtualProtect(void *func, unsigned long long byteCount, unsigned long flags, unsigned long *oldFlags);
extern "C" __declspec(dllimport) int WINCALL VirtualProtect(void *func, unsigned long byteCount, unsigned long flags, unsigned long *oldFlags);
Should be something like:
}
// De-windows.h-ified import to avoid including that file.
extern "C" __declspec(dllimport) int WINCALL VirtualProtect(void *func, unsigned long long byteCount, unsigned long flags, unsigned long *oldFlags);
extern "C" __declspec(dllimport) int WINCALL VirtualProtect(void *func, unsigned long byteCount, unsigned long flags, unsigned long *oldFlags);
OS: Android 7.0
Android Studio: 2.2.3
NDK: 13.1.3345770
cmake: (min) 3.4.1
test project: https://github.com/games-neox/hippomocks_test0
same code/test does work on an armeabi-v7a device/emulator
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.
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?
The assembla page from 2009 is version 3.1. What version are we on now? Need one for a manifest:-(
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.
I cannot catch any exception when mocking static functions. (using a decent g++ compiler under linux)
A minimal example:
http://coliru.stacked-crooked.com/a/1f5ea78f50a29b3d
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));
}
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;
}
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
Patch to follow
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.
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;
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?
The README is missing some information like where to find the latest stable release. On a related topic, any plan to do another stable release?
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).
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:
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!
Generally speaking seems to me that there are general portability problems in hippomock source code. It should be a great tool solving problems as this one.
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.
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.
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);
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> ]
This uses other information from the vtable that is not currently available. TODO: figure out if it is possible to make this work.
The definition of the RAISE... macros have an error. The printf call must use c_str() on the err string:
printf("%s\n", err.c_str()); \
abort(); exit(-1); }
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.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.