jeudi 26 novembre 2015

Is it possible to write a c++ class template that automatically wraps and virtualizes non virtual interfaces?

The Problem

When writing unit tests one often needs mock objects. In order to make the prodcution object replaceable, the mock object class derives from the production object class and overrides some virtual functions.

The problem arrises when the production class has no virtual functions and it is not within your power to change that. For now i see two choices to solve the problem.

  1. Turn your class into a class template that is parameterized by the subsystems type. The your production class will be MyClass<ProductionSubsystem> and for the tests on would use MyClass<MockSubsystem>

  2. Manually write a wrapper with virtual function that call the non virtual functions of the wrapped subsystem class. Then mock the wrapper.

I am not entirely happy with any of the two options. 1 forces me to turn my "simple" class into a class template and 2 forces me to write a lot of boiler plate code.

So I was wondering if one could automate the process of writting a wrapper for the non virtual class. I imagine something like this:

// The subsystem that contains the production code
class Interface
{
    void nonVirtualFunction();
}

// Contains the same functions as Interface but does not derive from it
class Implementation
{
    void nonVirtualFunction();
};

// wrapper base class that provides the virtual interface
template<typename Interface>
class AutoWrapper
{
    // Do some magic to provide the same functions that Interface has, but virtual.
}

// Class to provide the interface of AutoWrapper<Interface> but calls the functions in Implentation.
template<typename Implementation, template Interface>
class AutoWrapperImpl 
{ 
    // do some other magic here ... 
};

This setup should allow the following use case:

// code using the AutoWrapper
void useAutoWrapper()
{
    AutoWrapper<Interface> wrapper = new AutoWrapper<Interface>();
    wrapper->nonVirtualFunction();    // calls Interface::nonVirtualFunction()

    wrapper = new AutoWrapperImpl<Interface,Implementation>();
    wrapper->nonVirtualFunction();    // calls Implementaion::nonVirtualFunction()
}

The Question

Is it possible in C++ to implement the two classes AutoWrapper and AutoWrapperImpl? If it is, how is it done and is there a solution publicly available?

Aucun commentaire:

Enregistrer un commentaire