How do I test abstract classes in C++ using the Google Test framework?

Viewed 1146

I use the Google Test framework to write unit tests for C++ code. Among other tests, I want to test the correct construction of objects of different classes that are all derived from one abstract class. Let's start with the abstract class:

class AbstractClass
{
    public:
        virtual ~AbstractClass() = default;
        std::string getName() const { return name_; }
        std::string toString() const { return toStringImpl(); }

    protected:
        AbstractClass(std::string name) : name_(name) {}

    private:
        virtual std::string toStringImpl() const = 0;
        std::string name_;
};

It has the function getName() that is implemented by the abstract class itsself. And it has a toString() function whose implementation is delegated to the derived classes by the private pure virtual function toStringImpl(). toString() is not much of interest here, but its concept makes this class abstract.

I have two derived conctrete classes as follows:

class ConcreteClassA : public AbstractClass
{
    public:
        ConcreteClassA(std::string name) : AbstractClass(name) {}
    private:
        virtual std::string toStringImpl() const override { return ""; }
};

class ConcreteClassB : public AbstractClass
{
    public:
        ConcreteClassB(std::string name) : AbstractClass(name) {}
    private:
        virtual std::string toStringImpl() const override { return ""; }
};

Nothing special, just the fact that the constructor of the abstract class is called during the construction of these concrete classes.

If I want to test the correct construction, I can of course write all tests for all derived classes like in the following example where I include tests for functionalities of the abstract class:

class ConcreteClassATests : public ::testing::Test
{};

TEST_F(ConcreteClassATests, constructionSuccessful)
{
    ConcreteClassA a {"TestA"};
    ASSERT_EQ(a.getName(), "TestA");
}

class ConcreteClassBTests : public ::testing::Test
{};

TEST_F(ConcreteClassBTests, constructionSuccessful)
{
    ConcreteClassB b {"TestB"};
    ASSERT_EQ(b.getName(), "TestB");
}

Given m derived classes and n tests for content of the abstract class, this will result in m*n handwritten tests. I think this should be solved with n handwritten tests (resulting either in n or m*n executed tests).

I already read about Value-Parameterized Abstract Tests which sound promising and also about Typed Tests, but it looks like this would only apply to testing functions that receive input and output a result. I am not sure if those concepts can be applied to test for a correct construction of objects.

So, can someone tell me if it is somehow possible to define the test for an "abstract feature" only once?


To reproduce and run my example, all snippets can be put together into one source file. Just add the following two lines on top and link against gmock_main and pthread:

#include <string>
#include <gmock/gmock.h>
0 Answers
Related