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.
Related
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'm attempting to use mocks to test that a certain method was called with certain arguments and am having trouble testing that *this is one of the arguments.
Here's the code under test:
class Component
{
virtual void update(Entity &entity, const uint32_t dt) {};
...
void Entity::update(const uint32_t dt)
{
for (unsigned int i = 0; i < components_.size(); ++i) {
components_[i]->update(*this, dt);
}
}
And the test:
ea_ = new aronnax::Entity(cla_);
EXPECT_CALL(mockComponent, update(Eq(ByRef(ea_)), testDt)).Times(1);
ea_->update(testDt);
I'm getting errors that the two types aren't comparable. I'm relatively new to c++ and am having trouble understanding how to compare the pointer ea_ to the pointer reference (*&) to ea_ passed into update.
Here's a complete working example. Note that the component method update must be declared with one of the MOCK_METHOD* macros. To check if an argument is a reference to some type, you use the Ref matcher. To bind to the reference with a pointer type, you must dereference the pointer as seen in the example.
Also, its important to understand that you must set the expectations on the object that is actually going to be called. I can't tell if your mock component is in the components container or not in your entity class, but I demonstrate the problems with not setting expectations on the correct object in the commented out portion in the test.
#include <stdint.h>
#include <gmock/gmock.h>
class Entity;
class Component
{
public:
MOCK_METHOD2(update, void(Entity&, uint32_t));
};
class Entity
{
public:
Entity(Component* c) : c_( c )
{
}
void update(uint32_t dt)
{
c_->update(*this, dt);
}
private:
Component* c_;
};
using ::testing::Ref;
TEST(MyTest, Component)
{
Component mockComponent;
Entity* ea = new Entity( &mockComponent );
EXPECT_CALL(mockComponent, update(Ref(*ea), 5));
ea->update( 5 );
// Component mockComponent2;
// Entity* ea2 = new Entity( &mockComponent );
// EXPECT_CALL(mockComponent2, update(Ref(*ea2), 5));
// ea2->update( 5 );
}
You may not need this, but it should allow you to quickly build the example if you have cmake.
cmake_minimum_required(VERSION 3.4)
include(CTest)
include(ExternalProject)
# Add googletest
ExternalProject_Add( googletest
GIT_REPOSITORY https://github.com/google/googletest.git
CMAKE_ARGS = "-Dgtest_disable_pthreads=1"
# Don't run update
UPDATE_COMMAND ""
# Disable install step
INSTALL_COMMAND ""
# BUILD_BYPRODUCTS googletest-prefix/src/googletest-stamp/googletest-gitinfo.txt
# BUILD_BYPRODUCTS googletest-prefix/tmp/googletest-cfgcmd.txt
BUILD_BYPRODUCTS "googletest-prefix/src/googletest-build/googlemock/libgmock_main.a"
)
# Get include dirs for googletest framework
ExternalProject_Get_Property(googletest source_dir)
set(GTEST_INCLUDE_DIRS
${source_dir}/googlemock/include
${source_dir}/googletest/include
)
# Create library target for gmock main, which is used to create
# test executables
ExternalProject_Get_Property(googletest binary_dir)
set(GTEST_LIBRARY_PATH ${binary_dir}/googlemock/libgmock_main.a)
set(GTEST_LIBRARY gmock_main)
add_library(${GTEST_LIBRARY} UNKNOWN IMPORTED)
set_property(TARGET ${GTEST_LIBRARY} PROPERTY IMPORTED_LOCATION ${GTEST_LIBRARY_PATH})
add_dependencies(${GTEST_LIBRARY} googletest)
add_executable(mytest main.cpp)
add_dependencies(mytest googletest)
target_include_directories(mytest BEFORE PRIVATE ${GTEST_INCLUDE_DIRS})
target_link_libraries(mytest gmock_main)
add_test(NAME mytest COMMAND mytest)
If you run the example, it should give you the following output.
$ ./mytest.exe
Running main() from gmock_main.cc
[==========] Running 1 test from 1 test case.
[----------] Global test environment set-up.
[----------] 1 test from MyTest
[ RUN ] MyTest.Component
[ OK ] MyTest.Component (0 ms)
[----------] 1 test from MyTest (0 ms total)
[----------] Global test environment tear-down
[==========] 1 test from 1 test case ran. (0 ms total)
[ PASSED ] 1 test.
Hope this helps you :
instead of:
ea_ = new aronnax::Entity(cla_);
EXPECT_CALL(mockComponent, update(Eq(ByRef(ea_)), testDt)).Times(1);
ea_->update(testDt);
you should convert you pointer to a reference (note * inside ByRef):
ea_ = new aronnax::Entity(cla_);
EXPECT_CALL(mockComponent, update(Eq(ByRef(*ea_)), testDt)).Times(1);
ea_->update(testDt);
or simply define the object on the stack and pass it as is (it will be passed as a reference by the compiler):
aronnax::Entity ea_(cla_); // NOT a pointer any more
EXPECT_CALL(mockComponent, update(Eq(ByRef(ea_)), testDt)).Times(1);<br>
ea_->update(testDt);
I know that the unit test for Java is very simple. We just need use JUnit and run test classes as JUnit test.
Now I'm working with C++ and I find a test library: cppunit.
It seems that I need to run my test with a specific function main.
However, a cpp project can have ONLY ONE main.
What should I do? I have to switch mains when I do my test and when I run my project?
What should I do? I have to switch mains when I do my test and when I run my project?
You should separate the code to test into a library project, that can be linked from your target application and the unit test runner.
Then have two more projects providing a main() function:
one for the target app, that just forwards main() implementation to a call of a MyTargetApp class member function, e.g. MyTargetApp::run()
one for the unit testing, that calls a TestRunner, and contains all of the test suite and fixture classes (including these for the MyTargetApp).
The target application project can be configured without linking against the cppunit library and your test suite/fixture implementations (which will certainly reduce the final artifacts footprint).
However, a cpp project can have ONLY ONE main.
Another option is to use just one project with a narrow main() function that can be compiled using a conditional preprocessor statement (as from their example on the TestRunner class):
#ifdef TESTING
int runUnitTests(int argc, char* argv[]);
#endif
int main(int argc, char* argv[]) {
#ifdef TESTING
// run the unit tests
// -----------------------------------------------------------------
return runUnitTests(argc,argv);
#else
// run the application
// -----------------------------------------------------------------
MyTargetApp app;
return app.run(argc,argv);
#endif
#ifdef TESTING
int runUnitTests(int argc, char* argv[]) {
std::string testPath = (argc > 1) ? std::string(argv[1]) : "";
// Create the event manager and test controller
CppUnit::TestResult controller;
// Add a listener that colllects test result
CppUnit::TestResultCollector result;
controller.addListener( &result );
// Add a listener that print dots as test run.
CppUnit::TextTestProgressListener progress;
controller.addListener( &progress );
// Add the top suite to the test runner
CppUnit::TestRunner runner;
runner.addTest( CppUnit::TestFactoryRegistry::getRegistry().makeTest() );
try {
std::cout << "Running " << testPath;
runner.run( controller, testPath );
std::cerr << std::endl;
// Print test in a compiler compatible format.
CppUnit::CompilerOutputter outputter( &result, std::cerr );
outputter.write();
}
catch ( std::invalid_argument &e ) {
// Test path not resolved
std::cerr << std::endl
<< "ERROR: " << e.what()
<< std::endl;
return 0;
}
return result.wasSuccessful() ? 0 : 1;
}
#endif
Then have 2 different project configurations, one that defines TESTING and one without.
One disadvantage of this solution is though, you'll get all the unit test suites and fixtures left in your program, because cppunit macros will register and instantiate them automatically, regardless if the will be called from the execution path.
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 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.