mat007 / turtle

C++ mock object library for Boost

Home Page:http://turtle.sourceforge.net

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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);
}

@Aperion,

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.