mat007 / turtle

C++ mock object library for Boost

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

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Mock method with move type argument calls copy constructor

phogy opened this issue · comments

Hi!
I'm using Turtle to mock a class that has a method which takes a moveeable type with no copy constructor. In my case this is a simple function as such:

class IMyClass
{
   public:
      virtual void Function(std::unique_ptr<IArgument> argument) = 0;
};

For which I am mocking it as such:

MOCK_BASE_CLASS(MockIMyClass, IMyClass)
{
   MOCK_METHOD(Function, 1);
};

Trying to set up an expectation for this function causes the deleted copy constructor to be called, which does not compile. E.g.:

MockIMyClass myMock;
MOCK_EXPECT(myMock.Function).calls([](std::unique_ptr<IArgument> argument) { ... });

I can work around this by making a detour through

MOCK_BASE_CLASS(MockIMyClass, IMyClass)
{
   void Function(std::unique_ptr<IArgument> argument) override
   {
       MockFunction(argument);
   }
   MOCK_METHOD(MockFunction, 1, void(std::unique_ptr<IArgument>&));
}

and make my expectation lambda on the MockFunction mock.

I saw that there were some related commits made in the repo three weeks ago, which got my hopes up. However, the unit test attached only tests the MOCK_FUNCTOR being possible to mock expect using a lambda with a unique pointer, but not a member function as in my case.

Hoping for some guidance (but tbh I can manage with the work around for now).
Best regards,
Christopher

Hi,

So this is similar to https://sourceforge.net/p/turtle/tickets/67 which #35 and #39 should fix.
Obviously this has not been released yet, I'm sorting out CI issues in order to be able to make a new release with enough confidence it will be stable, see #41 (the PR name is a bit misleading as this actually has a much broader scope).

If needed you can still grab a zip from https://github.com/mat007/turtle/archive/master.zip, extract the include folder and give it a try.

As for the unit test only checking for MOCK_FUNCTOR, it should not be a problem as most of the plumbing underneath is the same.
The second PR has more unit tests and should cover everything I believe.

Hi and thanks for your fast reply!
Actually I did see those fixes on master and tried my use case with the tip of master of yesterday (merge of #40). Problem is that the deleted copy constructor is now called already in the MOCK_METHOD declaration of the mock.
Here's a failing Boost test case that I'm running towards #41 (tip of fix-c++17-compliance):

class IClassWithMove
{
public:
    virtual void Function(std::unique_ptr<int> argument) = 0;
};

MOCK_BASE_CLASS(MockIClassWithMove, IClassWithMove)
{
    MOCK_METHOD(Function, 1);
};

BOOST_AUTO_TEST_CASE(TestClassWithMove)
{
    MockIClassWithMove mock;
    MOCK_EXPECT(mock.Function).once().calls([](std::unique_ptr<int> argument) { 
          BOOST_CHECK(*argument == 1); 
    });

    auto ptr = std::make_unique<int>(1);
    dynamic_cast<IClassWithMove&>(mock).Function(std::move(ptr));
}

On the line of MOCK_METHOD(..) this gives me:

error C2280: 'std::unique_ptr<int,std::default_delete<_Ty>>::unique_ptr(const std::unique_ptr<_Ty,std::default_delete<_Ty>> &)': attempting to reference a deleted function

Thanks for your support!
Best regards,
Christopher

I see, thanks for the test case, I'll take a look as soon as possible!

This should be fixed, do not hesitate to re-open if needed !

Thanks for fixing this so quickly!

Best regards,
Christopher