Calls made to a function as part of the framework (ie matcher) increment the call count
Aperion opened this issue · comments
This occurs when using the with
constraint and mock classes.
I have not run this code but I hope it demonstrates the issue. It appears that calls made for the catcher are counted against the MOCK_EXPECT count
class Id
{
public:
virtual ~Id(){}
virtual std::string GetId() const = 0;
virtual void Copy(const Id& id) const = 0;
}
MOCK_BASE_CLASS(IdMock, Id)
{
public:
MOCK_CONST_METHOD(GetId, 0, std::string());
MOCK_CONST_METHOD(Copy, 1, void(const Id& id));
}
bool operator==(const Id& lhs, const IA& rhs)
{
return lhs.GetId() == rhs.GetId();
}
class IdCheckNCopy
{
public:
void CheckNCopy(const Id& a)
{
// one call to GetId
if(a.GetId() == "Id")
// one call to Copy
a.Copy(a);
}
}
BOOST_AUTO_TEST_CASE(SampleTest)
{
IdMock mocked;
// expect only one call for if(a.GetId() == "Id")
MOCK_EXPECT(mocked.GetID).once().returns("Id");
// only one call expected for a.Copy(a)
MOCK_EXPECT(mocked.Copy).once().with(mocked);
IdCheckNCopy checkNCopy;
// matcher makes two calls to .GetId() via operator==
checkNCopy.CheckNCopy(mocked);
}
class IdCopy
{
public:
void Copy(const Id& a)
{
// one call to GetId
a.Copy(a);
}
}
BOOST_AUTO_TEST_CASE(SampleTest)
{
IdMock mocked;
// only one call expected for a.Copy(a)
MOCK_EXPECT(mocked.Copy).once().with(mocked);
IdCopy copy;
// matcher makes two calls to .GetId() via operator==, none are expected;
copy.Copy(mocked);
}
Hi Aperion,
When you write
MOCK_EXPECT(mocked.Copy).once().with(mocked);
you tell the library to check that the argument received by Copy matches 'mocked' using operator== because with(mocked) is actually a short-cut for with(mock::equal(mocked)).
What you want instead seems to be
MOCK_EXPECT(mocked.Copy).once().with(mock::same(mocked));
See this reference section for the list of available built-in constraints.
I hope this helps !
MAT.
@mat007 Sorry it took so long to get back to you. That appears to work for references, but I get compilation errors for pointers, or specifically shared_pointers in my case. I'm now using references and it appears to be working fine.
The code that is causing the compilation error looks more like this:
class Id
{
public:
virtual ~Id(){}
virtual std::string GetId() = 0;
virtual void Copy(const Id& id)= 0;
virtual void Copy(std::shared_ptr<Id> id)= 0;
}
MOCK_BASE_CLASS(IdMock, Id)
{
public:
MOCK_CONST_METHOD(GetId, 0, std::string());
MOCK_NON_CONST_METHOD(Copy, 1, void(const Id& id), Copy_Ref);
MOCK_NON_CONST_METHOD(Copy, 1, void(std::shared_ptr<Id> id), Copy_Ptr);
}
class IdCopy
{
public:
void Copy(const Id& a)
{
a.Copy(a);
}
void Copy(std::shared_ptr<Id> a)
{
Copy(*a);
}
}
BOOST_AUTO_TEST_CASE(SampleTest)
{
auto std::shared_ptr<IdMock> mocked = std::make_shared<IdMock>();
// this causes turtle\constraints.hpp(73): error C2440: '==' : cannot convert from 'const hared_ptr<MockedClass> *const ' to 'const std::shared_ptr<MockedClass> *'
MOCK_EXPECT(mocked.Copy_ptr).once().with(std::same(mocked));
IdCopy copy;
copy.Copy(mocked);
}
The shared_ptr is copied around everywhere, there is no chance to be able to compare it with mock::same.
Here is what it should look like, after fixing a few error in the code you provided :
class Id
{
public:
virtual ~Id(){}
virtual std::string GetId() = 0;
virtual void Copy(const Id& id)= 0;
virtual void Copy(std::shared_ptr<Id> id)= 0;
};
MOCK_BASE_CLASS(IdMock, Id)
{
public:
MOCK_METHOD(GetId, 0, std::string());
MOCK_METHOD(Copy, 1, void(const Id& id), Copy_Ref);
MOCK_METHOD(Copy, 1, void(std::shared_ptr<Id> id), Copy_Ptr);
};
class IdCopy
{
public:
void Copy(const Id& )
{
//a.Copy(a);
}
void Copy(std::shared_ptr<Id> a)
{
Copy(*a);
}
};
BOOST_AUTO_TEST_CASE(SampleTest)
{
auto mocked = std::make_shared<IdMock>();
MOCK_EXPECT(mocked->Copy_Ptr).once().with(mocked);
IdCopy copy;
copy.Copy(mocked);
}
this uses with(mocked) which is actually a short-cut for with(mock::equal(mocked)) which compares by value the shared_ptr.
MAT.