I am starting to use googlemock with googletest but am getting an SEH exception that I can't figure out.
The error message is:
unknown file: error: SEH exception with code 0xc0000005 thrown in the test body.
I have read some similar questions on SO and elsewhere but am yet to find an answer for such a simple example.
i.e. This is happening on my real code, but I've also reproduced the error on the very simple example below. I am building with MSVC2008.
code that reproduces the error:
#include "gtest/gtest.h"
#include "gmock/gmock.h"
#include <iostream>
using testing::Exactly;
class Production
{
public:
virtual ~Production() {};
virtual void fn() = 0;
};
class ProductionCode : public Production
{
public:
virtual ~ProductionCode() {};
void fn()
{
std::cout << "CALLED ProductionCode::fn" << std::endl;
}
};
class MockProduction : public Production
{
public:
virtual ~MockProduction() {};
MOCK_METHOD0(fn, void());
};
class ProductionUser
{
public:
void methodUnderTest(Production *p)
{
p->fn();
}
};
TEST(ProductionTest, CallTheProductionFunction) {
ProductionCode p;
ASSERT_NO_THROW( p.fn() );
}
TEST(ProductionTest, CallTheMethodUnderTest) {
Production* p = new ProductionCode;
ProductionUser u;
ASSERT_NO_THROW( u.methodUnderTest(p) );
delete p;
}
TEST(ProductionTest, CallTheMethodUnderTestWithMock) {
MockProduction m;
EXPECT_CALL(m, fn())
.Times(Exactly(1));
ProductionUser u;
ASSERT_NO_THROW(u.methodUnderTest(&m));
}
my test output from the console:
[==========] Running 3 tests from 1 test case.
[----------] Global test environment set-up.
[----------] 3 tests from ProductionTest
[ RUN ] ProductionTest.CallTheProductionFunction
CALLED ProductionCode::fn
[ OK ] ProductionTest.CallTheProductionFunction (4 ms)
[ RUN ] ProductionTest.CallTheMethodUnderTest
CALLED ProductionCode::fn
[ OK ] ProductionTest.CallTheMethodUnderTest (2 ms)
[ RUN ] ProductionTest.CallTheMethodUnderTestWithMock
unknown file: error: SEH exception with code 0xc0000005 thrown in the test body.
[ FAILED ] ProductionTest.CallTheMethodUnderTestWithMock (0 ms)
[----------] 3 tests from ProductionTest (10 ms total)
[----------] Global test environment tear-down
[==========] 3 tests from 1 test case ran. (13 ms total)
[ PASSED ] 2 tests.
[ FAILED ] 1 test, listed below:
[ FAILED ] ProductionTest.CallTheMethodUnderTestWithMock
1 FAILED TEST
.\simple.cpp(59): ERROR: this mock object (used in test ProductionTest.CallTheMe
thodUnderTestWithMock) should be deleted but never is. Its address is #000000000
014F800.
ERROR: 1 leaked mock object found at program exit.
Press any key to continue . . .
I am using my own main function as follows:
#include "gtest/gtest.h"
#include "gmock/gmock.h"
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();
}
I am guessing that I am making a pretty basic mistake here, Can anyone see where I am going wrong?
Thanks!
[Original Edited to make code & console output match]
I think you could force gtest to don't cloak the exact exception (what might be done using the code:
::testing::GTEST_FLAG(catch_exceptions) = false;
or the same from the command line)
And if then you use a debugger, you easily get the stack. Or even if you don't, I expect *nix-like OS to write core file
I met the same problem when I compiled the gmock as DLL and linked it in another project.
After a lot of try, I found the reason is:
You have to compile the gmock and your project in the same configuration!
That means you have to compile the gmock in DEBUG(RELEASE) configuration, if you want to link it in the DEBUG(RELEASE) mode. If not, the
unknown file: error: SEH exception with code 0xc0000005 thrown in the test body.
always occurs.
I hope my experience could help you, though you may encounter this problem in a different scene.
I was getting this error because I was dereferencing a null pointer.
Related
I want to make several gtests which all have to have a connect in the beginning, and a disconnect in the end. The things that are tested in between vary. They look as such:
TEST_F(..., ...)
{
// Connect - always the same
EXPECT_CALL(...);
ASSERT_TRUE(...);
// different things happen
EXPECT_CALL(...);
EXPECT_CALL(...);
ASSERT_TRUE(...);
// Disconnect - always the same
EXPECT_CALL(...);
ASSERT_TRUE(...);
}
Hence, I would like to have something like this:
void connect()
{
EXPECT_CALL(...);
ASSERT_TRUE(...);
}
void disconnect()
{
EXPECT_CALL(...);
ASSERT_TRUE(...);
}
TEST_F(..., ...)
{
connect();
// different things happen
EXPECT_CALL(...);
EXPECT_CALL(...);
ASSERT_TRUE(...);
disconnect();
}
Is this possible? Are there smarter ways to solve this problem?
The other answer provides example how it's usually done - you'd likely put connect() in test fixture constructor and disconnect() in test fixture destructor. You may want to read this section of documentation to learn more.
To answer the question "Is this possible?" with some documentation (from Advanced googletest Topics):
You can use assertions in any C++ function. In particular, it doesn't have to be a method of the test fixture class. The one constraint is that assertions that generate a fatal failure (FAIL* and ASSERT_*) can only be used in void-returning functions.
Here is a full example for setting up the mock object in the test fixture, which is instantiated once for each TEST_F:
#include <gmock/gmock.h>
#include <gtest/gtest.h>
class Object {
public:
void someMethod();
};
class MockObject : public Object {
public:
MOCK_METHOD(void, someMethod, (), ());
};
class TestFixture : public testing::Test {
public:
MockObject object;
TestFixture() {
std::cout << "Creating fixture." << std::endl;
EXPECT_CALL(object, someMethod()).Times(1);
}
~TestFixture() { std::cout << "Destroying fixture." << std::endl; }
};
TEST_F(TestFixture, SomeTest1) {
std::cout << "Performing test 1." << std::endl;
object.someMethod();
}
TEST_F(TestFixture, SomeTest2) {
std::cout << "Performing test 2." << std::endl;
object.someMethod();
}
The example can be compiled with:
g++ $(pkg-config --cflags --libs gtest gtest_main gmock) test.cpp
The output would look like this:
$ ./a.out
Running main() from /build/gtest/src/googletest-release-1.10.0/googletest/src/gtest_main.cc
[==========] Running 2 tests from 1 test suite.
[----------] Global test environment set-up.
[----------] 2 tests from TestFixture
[ RUN ] TestFixture.SomeTest1
Creating fixture.
Performing test 1.
Destroying fixture.
[ OK ] TestFixture.SomeTest1 (0 ms)
[ RUN ] TestFixture.SomeTest2
Creating fixture.
Performing test 2.
Destroying fixture.
[ OK ] TestFixture.SomeTest2 (0 ms)
[----------] 2 tests from TestFixture (0 ms total)
[----------] Global test environment tear-down
[==========] 2 tests from 1 test suite ran. (0 ms total)
[ PASSED ] 2 tests.
TL;DR: You can use GMock to add mocking capability to your Microsoft native c++ unit tests. See my answer below for details.
I want to start adding mocks to my existing set of native unit tests. The tests are written using Microsoft's CppUnitTestFramework framework, which doesn't have support for mocking. I don't really want to convert the entire test suite to another framework just to add a few mocks.
Google's GMock framework seems to provide everything I need and the documentation suggests it can be used with frameworks other than gtest. So using advice from blog posts like this one, I created a couple of unit tests.
TEST_MODULE_INITIALIZE(ModuleInitialize)
{
// Enable google mock
GTEST_FLAG(throw_on_failure) = true;
int argc = 0;
TCHAR **argv = nullptr;
InitGoogleMock(&argc, argv);
}
TEST_CLASS(GMockTests)
{
public:
MockTestClass _mockObj;
TEST_METHOD(Method1_ParamIsOne_Method2CalledWithOne)
{
EXPECT_CALL(_mockObj, Method2(1)).Times(1);
_mockObj.Method1(1);
}
TEST_METHOD(Method1_ParamIsZero_IntentionallyFail)
{
// Expectation will fail
EXPECT_CALL(_mockObj, Method2(1)).Times(1);
_mockObj.Method1(0);
}
};
The results are less than satisfactory. The expectations do work (first method passes), but if any expectation fails the entire run is aborted with only the following unhelpful message in the test output:
[3/27/2019 11:39:17 AM Error] The active test run was aborted. Reason:
[3/27/2019 11:39:17 AM Informational] ========== Run test finished: 0 run (0:00:22.3042194) ==========
The Visual Studio Test Explorer window doesn't indicate what the problem is either. It just shows that one test succeeded and the other one didn't run:
So what I'm looking for from this integration is:
A GMock test failure doesn't abort the entire run.
Tests that fail GMock expectations are shown as failed.
All GMock messages should be shown in the test output.
I was able to get GMock working correctly with the CppUnitTestFramework by creating a custom TestEventListener. I then created a simple set of interface functions to make it easier to work with.
I used the gmock 1.7.0 NuGet package to install the GMock framework into my project, and added the two files shown below.
GMockUtils.h
#pragma once
#include <CppUnitTest.h>
#include <gmock/gmock.h>
namespace testing {
namespace GMockUtils {
// Call once per test class or module to set up everything needed by GoogleMock.
void InitGoogleMock();
// Call once per test method to check for GoogleMock messages.
void CheckGoogleMock();
}
}
GMockUtils.cpp
#include "stdafx.h"
#include "GMockUtils.h"
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
namespace testing {
namespace GMockUtils {
namespace {
// Test event listener for use with CppUnitTestFramework
class CppUnitTestReporter : public EmptyTestEventListener
{
public:
CppUnitTestReporter() : _failed(false)
{
}
// Helper for converting std::string to std::wstring
std::wstring to_wstring(const std::string& str) const
{
std::wstring output;
std::copy(str.begin(), str.end(), std::back_inserter(output));
return output;
}
// Called after a failed assertion or a SUCCEED() invocation.
void OnTestPartResult(const ::testing::TestPartResult& result) override
{
// Log this result to the CppUnitTestFramework output
Logger::WriteMessage(result.summary());
// Note: You cannot do an Assert directly from a listener, so we
// just store the messages until CheckGoogleMock() is called.
if (result.failed())
{
_failed = true;
// Append this result to the running summary
_failedSummary += result.message();
_failedSummary += "\n";
}
}
// Clear any previous failures
void ResetFailures()
{
_failed = false;
_failedSummary.clear();
}
// Assert if any failures have been detected. Also resets failures.
void CheckFailures()
{
auto failed = _failed;
auto failedSummary = _failedSummary;
ResetFailures();
Assert::IsFalse(failed, to_wstring(failedSummary).c_str());
}
protected:
bool _failed;
std::string _failedSummary;
} *_listener;
}
// Initialize the Google Mock framework for use with CppUnitTestFramework
void InitGoogleMock()
{
// Avoids calling the function unnecessarily
if (_listener != nullptr)
return;
// Dummy command line parameters (could pass exe path here)
int argc = 0;
char** argv = nullptr;
// Initialize the framework
::testing::InitGoogleMock(&argc, argv);
// We don't want exceptions thrown, regardless what the doc says
GTEST_FLAG(throw_on_failure) = false;
// Remove default listener
auto &listeners = UnitTest::GetInstance()->listeners();
delete listeners.Release(listeners.default_result_printer());
// Create and install the new listener
_listener = new CppUnitTestReporter();
listeners.Append(_listener);
}
// Reset any previous failures detected by the listener
void ResetGoogleMock()
{
_listener->ResetFailures();
}
// Prints messages and asserts if any Google Mock messages are found.
void CheckGoogleMock()
{
Assert::IsNotNull(_listener, L"Google Mock framework not initialized by InitGoogleMock()");
_listener->CheckFailures();
}
}
}
I use the GMockUtils functions in unit test classes like this:
#include "GMockUtils.h"
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
using namespace ::testing;
namespace GMockUtilsDemo
{
TEST_CLASS(GMockUtilTests)
{
public:
TEST_CLASS_INITIALIZE(ClassInitializer)
{
// IMPORTANT: This must be called before any mock object constructors
GMockUtils::InitGoogleMock();
}
TEST_METHOD_CLEANUP(MethodCleanup)
{
// Checks for GoogleMock messages. Asserts if found.
GMockUtils::CheckGoogleMock();
}
TEST_METHOD(Method1_ParamIsOne_Method2CalledWithOne)
{
MockTestClass mockObj;
EXPECT_CALL(mockObj, Method2(1)).Times(1); // Expectation will be met
mockObj.Method1(1);
}
TEST_METHOD(Method1_ParamIsZero_IntentionallyFail)
{
MockTestClass mockObj;
EXPECT_CALL(mockObj, Method2(1)).Times(1); // Expectation will not be met
mockObj.Method1(0);
}
};
}
The Console Output
The console output now shows all GMock messages, and the run does not abort on the first test failure.
[3/27/2019 12:23:46 PM Informational] ------ Run test started ------
[3/27/2019 12:23:46 PM Informational]
Unexpected mock function call - returning directly.
Function call: Method2(0)
Google Mock tried the following 1 expectation, but it didn't match:
c:\...\gmockutilsdemo.cpp(64): EXPECT_CALL(_mockObj, Method2(1))...
Expected arg #0: is equal to 1
Actual: 0
Expected: to be called once
Actual: never called - unsatisfied and active
[3/27/2019 12:23:46 PM Informational] Actual function call count doesn't match EXPECT_CALL(_mockObj, Method2(1))...
Expected: to be called once
Actual: never called - unsatisfied and active
[3/27/2019 12:23:46 PM Informational] ========== Run test finished: 2 run (0:00:00.8631468) ==========
Test Explorer View
If I run the tests via Visual Studio Test Explorer, I can also see all GMock messages related to a particular test. It also works with the VsTest task on Azure DevOps.
Hopefully this will be useful to anyone who finds themselves in the same situation.
I am new c++ so forgive me to be asking this question. I created a project and run it the first time, it is successful. But when i start another project and i added 4 classes to it (you can see from the tabs) and the main.cpp is unable to run. I am confused as the codes are exactly the same in both projects.
Run Successful:
Success
Build Successful but run failed:
Run Failed
What are the solutions to solve this problem?
Do i have to post codes of all my classes? (there are 8 files)
student.h:
#ifndef CLSSTUDENT_H
#define CLSSTUDENT_H
#include <string>
#include <iostream>
using namespace std;
class clsStudent {
protected:
string name;
string student_no;
string program;
public:
clsStudent(string n, string sn,string prog );
virtual void displayStudentDetails();
};
student.cpp
#include "TutorialClass.h"
void TutorialClass::addStudent(clsStudent std)
{
_students.push_back(std);
}
int TutorialClass::getStudentCount()
{
return _students.size();
}
void TutorialClass::display()
{
}
#endif /* CLSSTUDENT_H */
I open up a new project and added only this class. It is unable to run as well. What is the problem in the codes?
It seems that your program only fails to run when it's compiled with other files. My bet is that in these files you've got buggy code that is running before main() gets to run.
This can happen in cases like this:
int f() {
throw; // bam! Uncaught exception;
}
int x = f(); // this runs before main()
Or this:
class C {
C() {
cout << "This runs before main() too!" << endl;
}
};
C my_c; // calls constructor
In both cases: code was executed before main(). You want this because you want your global variables to be initialized before running main(). If this initialization code manages to crash the program via a segfault or an exit() call or throwing some exception which isn't caught? You've got a crashed program before it ever even gets the chance to run.
Has anyone ever seen seen odd behavior in gmock when following an ON_CALL statement with an EXPECT_CALL statement? For me, the EXPECT_CALL statement in the following code doesn't work (it doesn't actually enforce the Times part):
ON_CALL(myMockObject, myMockMethod()).WillByDefault(Return("hello mock")));
EXPECT_CALL(myMockObject, myMockMethod()).Times(99999);
myMockObject.myMockMethod();
Other solutions that I've tried:
Overriding the myMockMethod from the super class and have it simply return a string literal. The problem with this is that I can't determine how many times it's been called later on.
Skipping the ON_CALL part in favor of something like this:
EXPECT_CALL(myMockObject, myMockMethod())
.Times(1)
.WillRepeatedly(Return("hello mock"));
This results in a compilation error.
Also of note, the string literal I'm using in this example is custom in reality and something that gmock won't be able to come up with a default for (such as bool).
You have some other error in your original code which is not being mentioned in your question. The code provided in the question behaves as you expected if you construct a minimal self-contained example.
For example, the following code:
#include <string>
#include "gmock/gmock.h"
using ::testing::Return;
struct MyClass {
virtual ~MyClass() {}
virtual std::string myMockMethod() = 0;
};
struct MyMockClass : MyClass {
MOCK_METHOD0(myMockMethod, std::string());
};
TEST(MyClass, Fails) {
MyMockClass myMockObject;
ON_CALL(myMockObject, myMockMethod()).WillByDefault(Return("hello mock"));
EXPECT_CALL(myMockObject, myMockMethod()).Times(99999);
myMockObject.myMockMethod();
}
TEST(MyClass, Passes) {
MyMockClass myMockObject;
EXPECT_CALL(myMockObject, myMockMethod()).Times(1).WillRepeatedly(Return("hello mock"));
myMockObject.myMockMethod();
}
int main(int argc, char **argv) {
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
produces the following (expected) output:
[==========] Running 2 tests from 1 test case.
[----------] Global test environment set-up.
[==========] 2 tests from MyClass
[ RUN ] MyClass.Fails
..\src\main.cc(18): error: Actual function call count doesn't match EXPECT_CALL(myMockObject, myMockMethod())...
Expected: to be called 99999 times
Actual: called once - unsatisfied and active
[ FAILED ] MyClass.Fails (0 ms)
[ RUN ] MyClass.Passes
[ OK ] MyClass.Passes (0 ms)
[----------] 2 tests from MyClass (2 ms total)
[----------] Global test environment tear-down
[==========] 2 tests from 1 test case ran. (2 ms total)
[ PASSED ] 1 test.
[ FAILED ] 1 test, listed below:
[ FAILED ] MyClass.Fails
1 FAILED TEST
If you want your mock object to be held in a test fixture, you can do:
class MyClassTest : public testing::Test {
protected:
MyMockClass myMockObject_;
};
TEST_F(MyClassTest, Fails) {
ON_CALL(myMockObject_, myMockMethod()).WillByDefault(Return("hello mock"));
EXPECT_CALL(myMockObject_, myMockMethod()).Times(99999);
myMockObject_.myMockMethod();
}
Mock::VerifyAndClearExpectations(&myMockObject);
This did the trick. I'm still not sure how expectations are managed behind the scenes, but this got me working.
Any further explanation of this would be greatly appreciated, though.
I've just learned about value-parametrized unit tests in googletest and would like to use them in my project.
I wrote a simple parametrized test.
Header:
#include <gtest/gtest.h>
namespace EnsembleClustering {
class ParametrizedGTest: public testing::TestWithParam<int> {
public:
ParametrizedGTest();
virtual ~ParametrizedGTest();
};
} /* namespace EnsembleClustering */
Source:
#include "ParametrizedGTest.h"
namespace EnsembleClustering {
ParametrizedGTest::ParametrizedGTest() {
// TODO Auto-generated constructor stub
}
ParametrizedGTest::~ParametrizedGTest() {
// TODO Auto-generated destructor stub
}
TEST_P(ParametrizedGTest, testParameter) {
int n = GetParam();
EXPECT_EQ(n, GetParam());
}
INSTANTIATE_TEST_CASE_P(ParametrizedGTestInstance,
ParametrizedGTest,
::testing::Values(100));
} /* namespace EnsembleClustering */
Now, when I run googletest as usual, the program crashes without any output. The gdb stack trace is
EnsembleClustering-D [C/C++ Application]
EnsembleClustering
Thread [1] (Suspended : Signal : EXC_BAD_ACCESS:Could not access memory)
__gnu_debug::_Safe_sequence_base::_M_attach_single() at 0x100528add
__gnu_debug::_Safe_sequence_base::_M_attach() at 0x100528a74
__gnu_debug::_Safe_iterator_base::_M_attach() at 0x100528bfe
__gnu_debug::_Safe_iterator_base::_Safe_iterator_base() at safe_base.h:90 0x1000016e9
__gnu_debug::_Safe_iterator<__gnu_cxx::__normal_iterator<testing::internal::ParameterizedTestCaseInfoBase**, std::__cxx1998::vector<testing::internal::ParameterizedTestCaseInfoBase*, std::allocator<testing::internal::ParameterizedTestCaseInfoBase*> > >, std::__debug::vector<testing::internal::ParameterizedTestCaseInfoBase*, std::allocator<testing::internal::ParameterizedTestCaseInfoBase*> > >::_Safe_iterator() at safe_iterator.h:154 0x100002e9c
std::__debug::vector<testing::internal::ParameterizedTestCaseInfoBase*, std::allocator<testing::internal::ParameterizedTestCaseInfoBase*> >::begin() at vector:207 0x100001fbe
testing::internal::ParameterizedTestCaseRegistry::GetTestCasePatternHolder<EnsembleClustering::ParametrizedGTest>() at gtest-param-util.h:574 0x1000025b0
EnsembleClustering::ParametrizedGTest_testParameter_Test::AddToRegistry() at ParametrizedGTest.cpp:22 0x100001d3f
__static_initialization_and_destruction_0() at ParametrizedGTest.cpp:22 0x100001349
_GLOBAL__sub_I_ParametrizedGTest.cpp() at ParametrizedGTest.cpp:32 0x100001424
<...more frames...>
gdb
Am I doing something wrong or is this a bug in googletest? Can you reproduce this error?
EDIT: I am on Mac OS X 10.8.
From looking at the source code of gtest the only case if there are no parametrized tests available is on Windows using VC7.1 with disabled exceptions:
// We don't support MSVC 7.1 with exceptions disabled now. Therefore
// all the compilers we care about are adequate for supporting
// value-parameterized tests.
#define GTEST_HAS_PARAM_TEST 1
So, you'll need to check how your MinGW was built and probably update it? And can you run the gtest unit tests to see if they execute the typed parameters test?
More information on MinGW:
On their FAQ they report that when using MinGW the following compile option for building gtest is required: PATH/TO/configure CC="gcc -mno-cygwin" CXX="g++ -mno-cygwin".
Complete Example:
#include <gtest/gtest.h>
namespace EnsembleClustering {
class ParametrizedGTest: public testing::TestWithParam<int> {
public:
ParametrizedGTest();
virtual ~ParametrizedGTest();
};
ParametrizedGTest::ParametrizedGTest() {
}
ParametrizedGTest::~ParametrizedGTest() {
}
TEST_P(ParametrizedGTest, testParameter) {
int n = GetParam();
EXPECT_EQ(n, GetParam());
}
INSTANTIATE_TEST_CASE_P(ParametrizedGTestInstance,
ParametrizedGTest,
::testing::Values(100));
} /* namespace EnsembleClustering */
int main(int argc, char* argv[]) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
I compiled this code using the following compiler call on Mac OS X 10.8:
g++ -IGTEST_INCLUDE_DIR -LGTEST_LIB_DIR -lgtest -o tt2 tt2.cpp
Where GTEST_INCLUDE_DIR and GTEST_LIB_DIR are the path where header and library files are stored. When you compile and execute, what happens?
Thanks #ChristianStaudt and #grundprinzip
I would like to point future readers to following link that explains this problem.
http://libcwd.sourceforge.net/reference-manual/group__enable__glibcxx__debug.html
This is a link to the documentation for GLIBCXX_DEBUG flag. It states the following important points.
"Note that this flag changes the sizes and behavior of standard class templates such as std::vector, and therefore you can only link code compiled with debug mode and code compiled without debug mode if no instantiation of a container is passed between the two translation units."
"When to use it
It is a good idea to use this if you suspect problems related to iterators."
Now, if you look at the stack trace posted originally, the crash happens due to vector<testing::internal::ParameterizedTestCaseInfoBase*> as gtest tries to get an iterator on this container, using begin() method.
In my case, gtest lib was compiled without GLICXX_DEBUG flag, but my test code was compiled with this flag. The test code worked like a charm when I compiled without this flag.