FANDOM


The following instructions will get you compiling and using GoogleMocks.

Simple exampleEdit

  • Download gmock-1.4.0, and extract it somewhere.
  • Compile the GoogleMocks static-link library with Visual C++ 2005 by opening the msvc\gmock.sln solution and building the entire solution.
    You can also use Visual C++ 2008, but you'll get some warnings that you can safely ignore
    Use the version of the compiler you'll be compiling the unit tests with.
  • Using Visual C++, create a new C++ Win32 Console application.
    • In the Project Settings, change the Runtime Library setting under C++ / Code Generation to "Multi-threaded Debug (/MTd)" (from the default "Multi-threaded Debug DLL (/MDd)").
    • In the Project Settings, add the "include" and "gtest\include" paths of gmock-1.4.0 to the Additional Include Directories setting under C++ / General.
    • At the top of the CPP file of your console app, add:
#pragma comment( lib, "....\\msvc\\Debug\\gmock.lib")  // Fix this path to match your environment
    • Remove the existing _tmain() function, and add the following code to the CPP:
#include <gmock/gmock.h> 
#include <gtest/gtest.h> 
using ::testing::AtLeast;

class Turtle {
public:
  virtual ~Turtle() {} 
  virtual void PenUp() = 0; 
  virtual void PenDown() = 0; 
  virtual void Forward(int distance) = 0; 
  virtual void Turn(int degrees) = 0; 
  virtual void GoTo(int x, int y) = 0; 
  virtual int GetX() const = 0; 
  virtual int GetY() const = 0; 
};

class MockTurtle : public Turtle { 
 public: 
  MOCK_METHOD0(PenUp, void()); 
  MOCK_METHOD0(PenDown, void()); 
  MOCK_METHOD1(Forward, void(int distance)); 
  MOCK_METHOD1(Turn, void(int degrees)); 
  MOCK_METHOD2(GoTo, void(int x, int y)); 
  MOCK_CONST_METHOD0(GetX, int()); 
  MOCK_CONST_METHOD0(GetY, int()); 
};

class Painter
{
	Turtle*	turtle;
public:
	Painter( Turtle* turtle )
		:	turtle(turtle)
	{
	}

	bool DrawCircle(int, int, int)
	{
		turtle->PenDown();
		return true;
	}

};

TEST(PainterTest, CanDrawSomething) { 
  MockTurtle turtle;
  EXPECT_CALL(turtle, PenDown())
      .Times(AtLeast(1)); 
 
  Painter painter(&turtle);
 
  EXPECT_TRUE(painter.DrawCircle(0, 0, 10)); 
}
 
int main(int argc, char** argv) { 
  // The following line must be executed to initialize Google Mock 
  // (and Google Test) before running the tests. 
  ::testing::InitGoogleMock(&argc, argv); 
  return RUN_ALL_TESTS(); 
}

Using DLL versions of Runtime LibraryEdit

These instructions assume you already did the Simple example above. If you want to use the DLL versions of the Runtime Library, you have to modify the GoogleMocks project.

  1. Open msvc\gmock.sln Solution
  2. In the Project Settings of the gmock project, change the Runtime Library setting under C++ / Code Generation to "Multi-threaded Debug DLL (/MDd)"
  3. Do the same for your console application

Example using __stdcallEdit

class IFoo
{
public:
	virtual void __stdcall A() = 0;
};

class MockFoo : public IFoo
{
public:
	MOCK_METHOD0_WITH_CALLTYPE( __stdcall, A, void());
};

Using a different test framework (i.e. not GoogleTest)Edit

Just using GoogleMock from a console appEdit

Replace the main() function with this:

int __cdecl main(int argc, char** argv) { 
  // The following line causes Google Mock to throw an exception on failure, 
  // which will be interpreted by your testing framework as a test failure. 
  ::testing::GTEST_FLAG(throw_on_failure) = true; 
  try
  {
	  ::testing::InitGoogleMock(&argc, argv); 

          // do your own test stuff here.
  }
  catch(std::runtime_error& e)
  {
	  std::cout << e.what() << std::endl;
  }

Using GoogleMocks from a Visual Studio C++/CLR Test projectEdit

  • You need to use the version of GoogleMocks that uses the DLL version of the CRT
    See "Using DLL versions of Runtime Library" above.
  • In the Visual Studio C++/CLR Test project, set the Common Language Runtime Support to /clr, not /clr:safe or /clr:pure
  • Edit stdafx.h and make it look something like this:
#pragma once

#define _CRT_SECURE_NO_WARNINGS
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0501
#endif						

#include <stdio.h>
#include <tchar.h>
#include <atlbase.h>
  • In the AssemblyInfo.cpp file, or some other file, add the following at the top of the file, right below <stdafx.h> :
#include "VSGoogleMocksIntegration.h"

// Include the GoogleMocks static-link library.  Fix this path to match your environment
#pragma comment( lib, "Y:\\AAMXCoreDev\\src\\BaseRuntimeComponentServer\\UnitTests2\\gmock-1.4.0\\msvc\\Debug\\gmock.lib")

// Initliaze GoogleMocks by creating this global object.  The one-time initialization code is in the constructor.
AAGoogleMockInitializer g_AAGoogleMockInitializer;
This initializes GoogleMocks
Be sure to fix the path to gmock.lib
  • Add the VSGoogleMocksIntegration.h somewhere where your project will find it.

VSGoogleMocksIntegration.hEdit

#pragma once

#pragma unmanaged
#include <gmock/gmock.h> 
#include <gtest/gtest.h> 
#pragma managed

#include <msclr\marshal_cppstd.h>

// While a test is running, this refers to that test's TextContext.
// GoogleMocks having access to the current test's TextContext can use it to report output to the screen.
public ref class TestContextSingleton
{
public:
	static Microsoft::VisualStudio::TestTools::UnitTesting::TestContext^ CurrentTestContext = nullptr;
};

// This is a "printer" we supply to GoogleMocks, so it doesn't output to the console
// (not console in a Visual Studio Test).  We use this to direct the test output to the Visual Studio test output screen
class MinimalistPrinter : public ::testing::EmptyTestEventListener
{
    // Called before a test starts.
    virtual void OnTestStart(const ::testing::TestInfo& test_info)
	{
		if ( TestContextSingleton::CurrentTestContext != nullptr )
		{
			TestContextSingleton::CurrentTestContext->WriteLine( "*** Test {0}.{1} starting.",
				msclr::interop::marshal_as<System::String^>( test_info.test_case_name() ),
				msclr::interop::marshal_as<System::String^>( test_info.name() )
			);
		}
		else
		{
			TestContextSingleton::CurrentTestContext->WriteLine( "OnTestStart() called with no CurrentTestContext" );
		}
    }

    // Called after a failed assertion or a SUCCESS().
    virtual void OnTestPartResult( const ::testing::TestPartResult& test_part_result)
	{
		if ( TestContextSingleton::CurrentTestContext != nullptr )
		{
			TestContextSingleton::CurrentTestContext->WriteLine( "{0} in {0}:{0}",
				msclr::interop::marshal_as<System::String^>( test_part_result.failed() ? "*** Failure" : "Success" ),
				msclr::interop::marshal_as<System::String^>( test_part_result.file_name() ),
				test_part_result.line_number()
			);

			TestContextSingleton::CurrentTestContext->WriteLine(
				msclr::interop::marshal_as<System::String^>( test_part_result.summary() )
			);
		}
		else
		{
			TestContextSingleton::CurrentTestContext->WriteLine( "OnTestPartResult() called with no CurrentTestContext" );
		}
    }

    // Called after a test ends.
    virtual void OnTestEnd(const ::testing::TestInfo& test_info)
	{
		if ( TestContextSingleton::CurrentTestContext != nullptr )
		{
			TestContextSingleton::CurrentTestContext->WriteLine( "*** Test {0}.{0} ending.",
				msclr::interop::marshal_as<System::String^>( test_info.test_case_name() ),
				msclr::interop::marshal_as<System::String^>( test_info.name() )
			);
		}
		else
		{
			TestContextSingleton::CurrentTestContext->WriteLine( "OnTestEnd() called with no CurrentTestContext" );
		}
    }
};

#pragma unmanaged
// A single instance of this created as a global variable.  In the constructor we
// initialize GoogleMocks, ensuring that all required set up is done before any tests
// are run.
class AAGoogleMockInitializer
{
public:
	AAGoogleMockInitializer()
	{
		try
		{
			::testing::GTEST_FLAG(throw_on_failure) = false;
			::testing::GTEST_FLAG(catch_exceptions) = true;
			::testing::GTEST_FLAG(break_on_failure) = false;

			// Get the name of the EXE so we can simulate parameters to main()
			wchar_t name[MAX_PATH];
			::GetModuleFileNameW(NULL, name, MAX_PATH);

			int			argc = 1;
			wchar_t*	argv1 = name;
			wchar_t**	argv = &argv1;
			::testing::InitGoogleMock(&argc, argv); 

			// Gets hold of the event listener list.
			::testing::TestEventListeners& listeners = ::testing::UnitTest::GetInstance()->listeners();

			// delete the default.
			delete listeners.Release(listeners.default_result_printer());

			// Adds a listener to the end.  Google Test takes the ownership.
			listeners.Append(new MinimalistPrinter);
		}
		catch(std::runtime_error&)
		{
			throw; // don't do this in production code.
		}
	}
};
#pragma managed
  • Create a C++/CLR Unit test .cpp file
    • At the top of the file, right below #include <stdafx.h>, add:
#pragma unmanaged
#include <gmock/gmock.h> 
#include <gtest/gtest.h> 
using ::testing::AtLeast;
#pragma managed

#include <msclr\marshal_cppstd.h>
#include "VSGoogleMocksIntegration.h"
#include "COMComponentDLL.h"
    • If testing COM objects, add a #include for the MIDL generated header file from the production component build. Example:
#include "..\MyComponent.h"
(Above assumes that the Unit Test project resides in a sub-folder of the production component source code, hence the ..\ in the path)
    • Create mock class for the interface you want to mock. Let's assume you have a COM interface called IBar
    MIDL_INTERFACE("12341234-1234-1234-1234-123412341234")
    IBar : public IPersistStream
    {
    public:
        virtual HRESULT STDMETHODCALLTYPE GetDrink() = 0;
    };

This is what the mock class would look like:

class MockIFoo : public IFoo {
 public:
  MOCK_METHOD2_WITH_CALLTYPE( __stdcall, QueryInterface, HRESULT(REFIID riid, void **ppvObject));
  MOCK_METHOD0_WITH_CALLTYPE( __stdcall, AddRef, ULONG());
  MOCK_METHOD0_WITH_CALLTYPE( __stdcall, Release, ULONG());
  MOCK_METHOD0_WITH_CALLTYPE( __stdcall, IsDirty, HRESULT());
  MOCK_METHOD1_WITH_CALLTYPE( __stdcall, GetClassID, HRESULT(CLSID *pClassID));
  MOCK_METHOD1_WITH_CALLTYPE( __stdcall, Load, HRESULT(IStream *pStm));
  MOCK_METHOD2_WITH_CALLTYPE( __stdcall, Save, HRESULT(IStream *pStm, BOOL fClearDirty));
  MOCK_METHOD1_WITH_CALLTYPE( __stdcall, GetSizeMax, HRESULT(ULARGE_INTEGER *pcbSize));
  MOCK_METHOD1_WITH_CALLTYPE( __stdcall, Drink, HRESULT());
};
  • Notice the special "_WITH_CALLTYPE" Macros. This is so that we can specify __stdcall (for COM methods)
    Note that base class methods are also included (IPersistStream, etc.)
  • Now you can use the Mock class in your test. Example:
    MockIFoo mockIFoo;

    EXPECT_CALL(mockIFoo, GetDrink())
        .Times(AtLeast(1)); 

Automatically generate mock classes from C++ codeEdit

Works fairly well. Doesn't work for COM interface. See:

https://github.com/google/googletest/tree/master/googlemock/scripts

Ad blocker interference detected!


Wikia is a free-to-use site that makes money from advertising. We have a modified experience for viewers using ad blockers

Wikia is not accessible if you’ve made further modifications. Remove the custom ad blocker rule(s) and the page will load as expected.