I have a test that works fine with a raw pointer, but I'm having trouble getting it work with a std::shared_ptr
. The class is like this:
class MyClass
{
MyClass(SomeService *service);
void DoIt();
}
My test code is like:
class MyClassTests : public ::testing::Test
{
public:
MyClassTests():
myClass_(new MyClass(&service_))
{}
protected:
SomeServiceFake service_;
MyClassSharedPointer myClass_;
};
TEST_F(MyClassTests, DoIt_DoesNotMeetCriteria_DoesNotPerformAction) {
// Arrange
EXPECT_CALL(service_, MeetsCriteria(_))
.WillRepeatedly(Return(false));
EXPECT_CALL(service_, PerformAction(_))
.Times(0);
// Act
myClass_->DoIt();
}
In this test, service_
is a mock/fake created on the stack in the test and I pass the address into the constructor of MyClass
. Changing MyClass
to take service
as a shared_ptr
, my new class looks like:
class MyClass
{
MyClass(std::shared_ptr<SomeService> service);
DoIt();
}
What I'm trying in my test is:
class MyClassTests : public ::testing::Test
{
public:
MyClassTests():
myClass_(new MyClass(std::shared_ptr<SomeService>(&service_)))
{
}
...
When I do this, however, the test fails with a:
Debug Assertion Failed!
Expression: _CtrlIsValidHeapPointer(pUserData)
In a nutshell, I need a shared_ptr
to service_
(which is a fake object) to pass to the MyClass
constructor and I need a non-pointer for the EXPECT_CALL
function. How can I get this to work correctly?
UPDATE
Tried dynamically allocating SomeServiceFake to get the shared_ptr and then using the * operator on service_
, this gets me "further" but now I get the following error:
error : this mock object
(used in test MyClassTests.DoIt_DoesNotMeetCriteria_DoesNotPerformAction)
should be deleted but never is. Its address is @009BBA68.
1>EXEC : error : 1 leaked mock object found at program exit.
UPDATE 2
Using Mock::AllowLeak(service_.get());
so I can get around this problem for now. Hopefully I'll get an answer.
Define your test class more like this:
class MyClassTests : public ::testing::Test {
public:
MyClassTests():
service_(new SomeServiceFake), myClass_(new MyClass(service_)) {}
protected:
std::shared_ptr<SomeServiceFake> service_;
std::shared_ptr<MyClass> myClass_;
};
and your test:
EXPECT_CALL(*service_, MeetsCriteria(_))
.WillRepeatedly(Return(false));
EXPECT_CALL(*service_, PerformAction(_))
.Times(0);
This has nothing to do with the test framework. As you said yourself, you are creating a shared_ptr from a stack-allocated object (i.e. one with automatic lifetime). This does not make sense. Shared pointers are typically created from the result of new
. You might be able to make it work if you pass a custom Deleter as the second argument to the shared_ptr constructor, but best might be to just create the object using new.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With