Search code examples
c++unit-testingboost-testturtle-mock

How to make expectations on a mock object created inside the tested object?


I want to unit test a class that looks like this:

template <typename T>
class MyClass {
...
    void someMethod() {
        T object;
        object.doSomething();
    }
...
};

I want to unit test this class, so I create a mock class for T:

struct MockT {
...
    MOCK_METHOD(doSomething, 0, void());
...
};

Then I want to use it in a test case:

BOOST_AUTO_TEST_CASE(testSomeMethod) {
    MyClass<MockT> myClassUnderTest;
    MOCK_EXPECT(???)....;
    myClassUnderTest.someMethod();
}

How do I make an expectation for this object? My first idea was to store all created MockT instances in a static container from the constructor, then delete them from the container from the destructor. This would work if the object were created in a different method than where it is used, like this:

myClassUnderTest.createTheObject();
MOCK_EXPECT(MockT::findMyObject().doSomething);
myClassUnderTest.useTheObject();

But for this I would need to modify the interface of my class, and I really don't want to do that. Is there anything else I can do?


Solution

  • I found that the best is to use a shared pointer for the member. It is unfortunate that I have to use an extra indirection just because of the unit test, but at least it works well.

    template <typename T, typename TFactory>
    class MyClass {
    ...
        void someMethod() {
            std::shared_ptr<T> object = factory();
            object->doSomething();
        }
    ...
        TFactory factory;
    };
    

    Then in the test it looks something like this:

    BOOST_AUTO_TEST_CASE(testSomeMethod) {
        std::shared_ptr<T> mockT;
        MockTFactory factory(mockT);
        MyClass<MockT, MockTFactory> myClassUnderTest(factory);
        MOCK_EXPECT(mockT->doSomething).once();
        myClassUnderTest.someMethod();
    }