How to use GoogleMock in Visual Studio? - c++

This is going to be a self-answered, FAQ-style question. See answer below.
With Visual Studio 2017/2019 it is really easy to set up a new Google Test project and start writing tests (as long as you don't mind using older versions of GoogleTest versions anyway).
But what about using GoogleMock as well? You would think that since Google combined gtest/gmock some time ago that this would just work. Just #include "gmock/gmock.h" and mock away. But no, the GoogleTest NuGet package that is automatically added by the template does not include the gmock folder at all.
Trying to add a second GoogleMock NuGet package causes multiple problems, such as mismatched gtest/gmock versions, overlapping include paths, etc.
Replacing the Microsoft GoogleTest NuGet package with the one from Google causes a link error:
MSVCRTD.lib(exe_main.obj) : error LNK2019: unresolved external symbol _main referenced in function "int __cdecl invoke_main(void)" (?invoke_main##YAHXZ)
So what is the current recommended (and least painful) way to set up GoogleTest/GoogleMock in Visual Studio? Tests should be able to be discovered, run, and debugged via the Test Explorer.

I've found two ways to set this up: Either compile the whole GoogleTest framework directly into each of the test projects, or create a library project to hold it. Using a library will give faster build times, but you'll need to make sure that compile/link options are the same on the library and the test projects.
Option 1: Compiling GoogleTest Directly in the Test Project
Create a new project from the Google Test template. Instructions here if needed.
Uninstall the Microsoft.googletest.v140.windesktop.msvcstl.static.rt-static NuGet package.
Install the latest gmock NuGet package from Google (currently v1.10.0).
Add the file gtest_main.cc to the project. It should be in ..\packages\gmock.1.10.0\lib\native\src\gtest\src\
At this point the project should look something like this (if it doesn't, try Unloading and Reloading the project):
The final configuration step is to disable use of Precompiled Headers for the three Google .cc files (Important: Notice the empty fields too).
Option 2: Using GoogleTest in a Static Library Project
Create a new project from the Static Library (C++) template. Instructions here if needed.
Delete all generated .h/.cpp files (pch.h, pch.cpp, framework.h, <ProjectName>.cpp, etc)
Install the latest gmock NuGet package from Google (currently v1.10.0).
Disable use of Precompiled Headers for the library project (see related pic above).
Create a new project from the Google Test template. Instructions here if needed.
Uninstall the Microsoft.googletest.v140.windesktop.msvcstl.static.rt-static NuGet package.
Add the file gtest_main.cc to the project. It should be in ..\packages\gmock.1.10.0\lib\native\src\gtest\src\
Disable use of Precompiled Headers for gtest_main.cc (see related pic above).
Add the library project to the test project's Project References.
Add ..\packages\gmock.1.10.0\lib\native\include\ to the test project's Include Directories under VC++ Directories
The solution structure should now look something like this:
Writing the Tests
Either way, you are now ready to start writing tests using GoogleMock. Add #include "gmock/gmock.h" to the pch.h file:
//
// pch.h
// Header for standard system include files.
//
#pragma once
#include "gtest/gtest.h"
#include "gmock/gmock.h"
Open the generated Test.cpp file and try it.
#include "pch.h"
class MockTest {
public:
MOCK_METHOD(void, SomeMethod, ());
};
TEST(TestCaseName, TestName) {
MockTest mock;
EXPECT_CALL(mock, SomeMethod);
mock.SomeMethod();
EXPECT_EQ(1, 1);
EXPECT_TRUE(true);
}

Related

Unit Testing DLL project on Windows using Google Test in VS 2022

I am trying to write unit tests for a larger, old project using GTest. The project compiles as a dll. Here is what the setup looks like: There are several projects inside the solution, and I am trying to add a Test Project to unit test on of the several projects.
As a proof of concept, I created a HelloWorld project, and a HelloWorldTest project in a different solution. To emulate my larger project, I changed the Configuration Type from .exe to .dll and ran into some errors. But these errors were resolved exporting classes/functions using __declspec(dllexport) along with including .lib in the project, and I am able to build and run the exe of the HelloWorldTest project.
I am trying to follow the same approach for my larger project by painstakingly adding EXPORT statements before classes/functions. However, I run into errors when I include required header files in the Test Project since the header file has other include statements which the Test Project does not understand about. For example, if I include "..\larger_project\custom_math.h" but custom_math.h has something like include "..\..\algo\somefile.h". (I've seen posts about referencing one project to another and have already done the same for my project.)
How do I resolve the issue of chained header file includes? I believe if I can resolve this, I should be able to create objects and start testing in my Test Project.
is there a better way to do this than adding EXPORT statements before every class/function?

C++ detours linking issue

I have problems building my code that is using static lib detours. I am trying to do an old basic CTF. For that I want to get into detours.
Whenever I try to build my .dll file I get an issue
LNK2019 unresolved external symbol _DetourTransactionBegin#0 referenced in function _DllMain#12
Now, I have built the detours library using 3 different version of the visual studio dev console.
I have tried firing 'vcvars32.bat' and then using nmake to build the library which was able to build it, but I get the above error during linking my .dll. I have also tried building it with 'vcvarsamd64_x86.bat' and then using nmake to build it which also was able to build the library, but I still get the same error as above during linking.
I have tried the usual stuff: the include folder for detours.h is added to C++/General/Additional Include Directories.
Under Linker/Additional Library Directories I added them as follows: "C:\temp\det_retry\lib.X64";"C:\temp\det_retry\lib.X86";%(AdditionalLibraryDirectories).
And also under Linker/Input/Additional Dependencies I have the following: detours.lib;%(AdditionalDependencies)
What am I missing here? This is a blocker for me for a couple of days and I am reiterating the same steps trying to figure out what's missing but I cannot see. I'd really appreciate the input.
I am sure I am using the newest version because I have downloaded (cloned) detours from the ms github page.
It appears your "Additional Library Directories" are setup incorrectly or contain invalid entries rather. They look like actual library file entries (i.e. pointing to some specific files) versus being only directories (e.g. "my/lib/path/for/my_project/"). Visual Studio's naming conventions are somewhat cryptic but they should be directory entries only. There should be an entry to whatever directory contains the detours.lib file (e.g. "MyProject/Libs/MSDetour" ... where MSDetour is a folder with the "detours.lib" in it) and then Visual Studio should find the library and link everything correctly.
As a side note, if you are using the Visual Studio developer console for building your project/solution you might want to look into CMake ... it is, in my opinion, significantly easier to work with (less "settings" digging) and maintain in the long-run.

How to see definitions in Visual Studio for files installed using vcpkg?

I'm using vcpkg library manager and with it I've installed gtk.
In VS2019 I have included #include "gtk/gtk.h" and when I Ctrl+Click on that line I end-up in that header file. Then I go to #include <gtk/gtkmain.h> and in there we see a bunch of interesting functions, for example gtk_init_abi_check. But this is only a declaration and I would like to see implementations (definitions) of these functions. RightMouseClick -> Go to declaration on function's name doesn't do anything.
Can I even use vcpkg for getting the libraries but also the code that I can read?
The simple way is to add gtk projects to your main Visual studio solution :
Download and extract vcpkg
Add all vcpkg projects
Search vcxproj in toolsrc present in the extracted folder (step 1)
Do same thing for vcpkg, vcpkglib and vcpkgtest if you want test project
Thea goal is to integrate gtk projects to your solution:
Now, you can use go to implementation
Remarque : If your main VS solution has a different version from the downloaded librarie, use Cmake to generate a new vcpkg, vcpkglib and vcpkgtest projects and do the same thing

Google Test pre-build VS 2013

I have a solution which was compiled with compiler VS2008. It was working perfect. It is instrumented with Google Test and the Google Test library is linked to the solution. the gtest.lib should be compiled with the same compiler as the solution itself, as far as I know.
Now, I have to compile this same solution with VS2013. I get this compilation error
Error 3 error LNK2038: mismatch detected for '_MSC_VER':
value '1700' doesn't match value '1800'
I think that I should get the library for Google Test compiled with Visual Studio 2013.
I cannot find such thing. Could you give me a hint at the Google Test library I should go for ?
The linker error you get is pretty obvious: You need a gtest.lib compiled with VS2013.
"I think that I should get the library for Google Test compiled with Visual Studio 2013."
Exactly, so just do that.
"Could you give me a hint at the Google Test library I should go for ?"
Well, no more as to cite from the google test primer documentation (emphasis mine), sorry (I doubt you can reliably download a proper binary elsewhere):
Setting up a New Test Project
To write a test program using Google Test, you need to compile Google Test into a library and link your test with it. We provide build files for some popular build systems: msvc/ for Visual Studio, xcode/ for Mac Xcode, make/ for GNU make, codegear/ for Borland C++ Builder, and the autotools script (deprecated) and CMakeLists.txt for CMake (recommended) in the Google Test root directory. If your build system is not on this list, you can take a look at make/Makefile to learn how Google Test should be compiled (basically you want to compile src/gtest-all.cc with GTEST_ROOT and GTEST_ROOT/include in the header search path, where GTEST_ROOT is the Google Test root directory).
Once you are able to compile the Google Test library, you should create a project or build target for your test program. Make sure you have GTEST_ROOT/include in the header search path so that the compiler can find "gtest/gtest.h" when compiling your test. Set up your test project to link with the Google Test library (for example, in Visual Studio, this is done by adding a dependency on gtest.vcproj).
If you still have questions, take a look at how Google Test's own tests are built and use them as examples.
I personally prefer to build the test runner using the src/gtest-all.cc to be built and linked with my test-projects from source. That's the most simple and mostly portable way IMHO (using e.g. your custom GNU makefiles).
As said in the comment on your OP, you can easily do a "prebuild" just using your VS2013 compiler, to link with it from other projects.
Note that there's a native GTEST package on NuGet which contains a gtest.lib. Has the additional benefit of making the gtest include folder automatically available.

Using Boost C++ unit tests with visual studio and can't find .cpp files in other project

I have a solution where I've added and setup boost unit tests. The problem is that I have another project I'd like to test that has some classes in it. In fact, that project is the main reason I added boost.
My project that needs testing is set to output as a .dll. And the problem is that, whenever my tests project needs to access code from the other projects, it can access the header just fine. However, if the header has unresolved code in it that's otherwise resolved in a .cpp file of the project with the objects, I receive a linking error. Is there a way around this? I'd ideally like to keep my objects in my other dll and then test them in my tests project.
You're probably not telling your test project where to find the symbols. Either link against your production code's .lib manually, or you can add the project as a reference and VS will link your projects automatically.
Go to your project's properties, under Common Properties choose Framework and References. Click the Add New References... button, and select your other project. Since it's a .dll, you then want to set Link Library Dependencies to False (save and reopen the dialog, that setting seems to be buggy).
The problem was that the visual studio compiler couldn't link to the CPP in the other files. I had to add the CPP files to the boost project as well using the existing files option.