The Skeptical Methodologist

Software, Rants and Management

C++ Dependency Injection, Part Deux

Last time I talked about a concept called Dependency Injection from the Java world, and compared it to Policy Based Design from the C++ world. The techniques that Java designers have used Dependency Injection for very easily ‘port’ to the Policy Based Design world – and one of these techniques, used in testing, is the idea of a mock framework. Mock frameworks are objects that ‘look, taste and smell’ like normal objects, but are used for purely testing purposes only and are useful in that the user can very closely control their state.

This time I’d like to go more into depth on a possible way to utilize Generic Dependency Injection, otherwise known as Policy Based Design, to build a mock object framework. I hope to show you that there are a few, for lack of a better term, ‘hacks’ that work very well for testing. They are hacks in that they aren’t all that pretty, however, I’d much rather utilize them to help keep testing concerns in testing code, rather than let our design and product reflect our testing procedure.

(On that note, I recall reading a post motivated by Test Driven Development and the creation of Mock Object frameworks, and the question of how to test private state. The answer the blogger gave was “make everything public”. In a world driven by tests, encapsulation takes a back seat. For shame, Java developers 🙂

Two important influences come from the Python world that I want to discuss. One is “Duck Typing” and the other is turning a compile time bug into a runtime bug on purpose. Duck Typing is a form of weak typing who’s premise is “If it quacks like a duck, it’s a duck.” That is, if I’m writing a method that requires an argument X and requires that X have a method of it’s own, called foo, then that’s all I need. I don’t need X to satisfy any type constraints, I just need to know that I can call X.foo() and not crash. This doesn’t even require a check for foo, as it’s considered bad form to call hasattr(X,”foo”) before a call to foo. Instead, good Pythonistas call first and ask questions later – basically by wrapping anything considered risky in a try/except block, and dealing with the attribute error raised by calling a method that doesn’t exist there.

Many people have noted that C++ templates are indeed very similar to Duck Typing. Absolutely no assumptions are made on a template, so if you have an X of some templated type, and you call X.foo, then the compiler just assumes you’ve done your due diligence and added that method in there somewhere. Pity on the designer who hasn’t, as a few pages of cryptic compiler errors are your reward. While C++ doesn’t allow this error to propagate into runtime like Python does, it does ‘weaken’ inheritance a bit. In Java, we use dependency-injection with object hierarchies, so we know whatever object we create on the other side fits some interface. C++ does not have that constraint(feature). This frees us up from some busy work of having to implement every single method on a large interface for each mock object, or enforcing some inheritance structure, which keeps tests light and easy to build.

(C++0x will have ways to levy interfaces on templates, called Concepts. However, these interfaces will be much more lightweight. It will be more in the style of the user asking “Here’s what I require” rather than the library telling “Here’s what I provide”. This will clear up many of the more cryptic template errors, as well as formalize STL concepts like the forward iterators, among other things, without the overhead of object hierarchies.)

In Python, there are no such things as interfaces or abstract base classes. Instead, interfaces are more or less defined by convention – one of these conventions is the idea of an ‘abstract method’ who’s sole purpose is to throw an exception if anyone calls him. They’ve effectively moved a compiler check into runtime, for better or worse. In the case of our tests, it’s for better.

The first thing we want to do is create a base mock class for every type we want to mock out. This type will resemble a Python ‘abstract’ class. It will inherit from all abstract base classes that our normal object does, and it will fulfill every abstract method – except every method will be nothing but throwing an exception.

Using this class as our ‘canvas’, we can now inherit one more time from this new mock object for any particular test we want to run. If we are testing our shape object’s ‘draw’ method, and we know(since we’re the designers) that shape’s draw calls a method on a ‘screen’ object called ‘getGraphics’, then we in turn just have to override one of our mock screen’s methods. The rest will still resolve to runtime exceptions. That way, we create very light mock objects for each test – in fact, we can create an entirely new hierarchy of types for each test, filling in the methods we want information on. For example:

namespace test1Detail {

class ScreenTest : MockScreen {

virtual Graphics getGraphics(){ … }

};

typedef Shape<ScreenTest> TestShape;

}

BOOST_AUTO_TEST( test1 ){

test1Detail::TestShape myShape;

…run test…

}

I now can add whatever behavior I want inside of getGraphics. And if my test calls any method BUT getGraphics, which is the only one I implemented for the test, I get a runtime error that will most likely be logged by my unit test library.

What kinds of things might I put inside these mock methods? Well lets say I am mocking a map object, like std::map. The object I’m testing is supposed to receive a message, and create a new object in it’s map with a key that’s also contained in the message.

Lucky for me I control the object at all points! I know exactly what message I’m sending to the object I’m testing, and I can set the key value to be whatever I want. Then, only a few lines away, in my detail namespace for that test, I’ve created a brand new class that ALSO has the key value I’m testing hard coded. In this case, I can override operator[] to make sure I’m attempting to add the right key.

Your mock objects that you intend to plug into testing are complete throwaway objects – you will only use the type once, so there’s really no gain in ‘designing’ the class well. In other words – make everything public. Hell, make everything public and static! Many of my mock objects are just a single method and a few static booleans I use as flags. You need to make most things static inside your mock objects so that you can access them from the type level. Look at the above example, and then think about how you’d check and make sure getGraphics was called with a certain argument.

…virtual Graphics getGraphics(int key){

if(key == 100){ //hard coded value

ScreenTest::KeyTestPassed = true;

} // rest of method

Now, at my TEST level, inside my BOOST_AUTO_TEST function, I can access the flag I just set, via the same resolution.

Test1Detail::ScreenTest::KeyTestPassed

For each test, we are creating a completely different type, not just a new object. And since we know exactly how many times this type will be instantiated, we can hard code different values and checks cowboy-style. The mock objects are completely throwaway, and are meant to simply be the quickest, dirtiest way to run our tests. Because the quicker we can write tests, the more test we are inclined to write.

Next time I hope to go over how we can extend our simple mock objects, giving us the ability to access individual instances. I also would like to make a few comments on applying RAII and review the template-know-how to make more advanced general use tests. Until then!

July 27, 2008 Posted by | Uncategorized | , , | Leave a comment

Dependency Injection in C++

My apologies on the double post – I accidentally clicked “create new page” :0)

A really valuable technique birthed in the Java world is the idea of dependency injection.  That is, instead of a class having to create it’s own object:

class Foo {

public Foo(){

bar = new Bar();

}

private Bar bar;

}

(forgive my Java, it’s been awhile.)

You pass in the object in its constructor, like this:

public Foo(Bar newBar) { bar = newBar; }

Of course, then, someone else has to be responsible for creating the bar object, so really, you end up just passing in object factories, or having a factory do all your setup for you.

(The passing in of object factories case):

interface BarFactory {

public Bar BuildBar();

}

class NormalBarFactor implements BarFactory {

public Bar BuildBar() { return new Bar(); }

}

class TestBarFactory implements BarFactory {

public TestBar BuildBar() { return new TestBar(); } //where TestBar inherits from Bar…

}

class Foo {

public Foo(BarFactory barFactory) { bar = barFactory.BuildBar() }

}

(And in the object configuration factory way…)

class Foo {

public Foo(Bar newBar) { bar = newBar; }

}

class FooBuilder{

public Foo BuildFoo() { return Foo(new Bar()) };

}

class TestFooBuilder{

public Foo BuildFoo() { return Foo(new TestBar()); }

}

As you can see, either of these approaches is really just variations on a theme.  The idea is that Foo, until runtime, does not know what kind of Bar it is using.  This provides two major benefits, one, as you can see above, it eases testing.  We can create test versions of objects, called “Mock Objects” to pass into the class we want to test.  These mock objects are simplified versions of objects that the tester controls very closely, making it easier to test Foo in isolation.  Additionally, with our mock objects being an example of this, this approach also allows infinitely configurable objects. This greatly increases reusablility of anything we build, and instead of going the old way of creating yet another object per configurable item, we instead just create the basic underlying class generically and plug in it’s dependencies when we need one.

For instance, if we needed a single threaded Foo and a multithreaded Foo, pure object inheritance and old style object oriented design might tell us to have both types of Foo inherit from some interface, and we differ their threading behavior based on the two implementations.  But now what if we have another variation in Foo’s, maybe we have one that is designed to deal with a certain protocol – say, deal with information coming in from the web, while another Foo is designed to deal with information coming in from a local database.  Now, really, we have to build 4 foos, a single threaded internet one, a single threaded database one, a multithreaded internet one, and a multithreaded database one.  Vary security policies, memory management issues, and other things, and you can see how object hierarchies can explode with what might be called “cross-cutting concerns.”

Using dependency injection solves this, by creating only one Foo object and allowing the caller to vary the threading policy or data sink independently, as needed.  This is also called the “Bridge Pattern”, among other things.  If you belong to the camp that claims patterns are simply proof of missing language features, then the Bridge Pattern might be seen as an object-oriented ‘solution’ to the problems solved by what’s called Aspect Oriented Programming, however, we’re not going to get into that right now.

There are some minor downsides to this approach, as it incurs a runtime penalty as all these polymorphic objects are created, and the caller must also know a little more about the object its creating – breaking encapsulation, to a degree.  Additionally, more overhead is required as a bunch of boilerplate factory objects need to be created.

For C++, you can use the exact same solution – pass in factory objects to another object’s constructor and then use the factory to configure the constructed object at runtime.  The same upsides and downsides exist.  However, luckily, with the use of templates, there is a better way.  The “factory” pattern used in dependency injection, if again, you belong to the camp that believes patterns are proof of missing language features, could be seen as an object-oriented solution to treating classes and types as first class objects.  That is, to say, in some languages, you cannot directly pass Types around by themselves, as arguments.  In languages that you can, such as via C++’s templates, the factory pattern disappears.

How does this affect dependency injection?  Well, since dependency injection, and the bridge pattern, make very heavy use of the factory pattern, it simplifies these two approaches a great deal.  And while pure aspect-oriented programming is still beyond C++’s reach, clever use of templates brings you very close.  I guess you could say that using templates to solve the bridge pattern is providing a generic solution to an aspect problem, rather than an object solution to an aspect problem.

To do “generic dependency injection”(GDI), which I’ll differentiate from “object dependency injection”(ODI) from here on out, in C++, you still go through the same mental processes in ODI to find the classes that you think may vary, or in the case of testing, you want to isolate your object from to test for.

class Foo {

public:

Foo() { bar = new Bar() }

private:

Bar * bar;

};

In the above, like our Java example, this class is still the Bar class.  We don’t want the Bar class to be coupled with our Foo class, which it currently is, but we don’t want the overhead of building all those object factories either.  And before anyone complains – yes, I know I left out the freeing of bar in the destructor, and moreover, it would have probably been easier just to make bar a value instead of a pointer, or used boost::shared_ptr.  We’ll be leaving out those details for simplicity.

Once we’ve recognized that Bar and Foo are coupled, we’ll pull out the Bar type into a template, rather than having Foo know about it.

template<typename BarType>

class Foo {

public:

Foo() { bar = new BarType() }

private:

BarType * bar;

}

Voila, now in our release code, we simply create Foo like this:

Foo<Bar> …

and in our test code, we create Foo like this:

Foo<TestBar> …

Our Foo object is completely decoupled from the type of Bar it’s using, at compile-time.  This increases runtime efficiency but maintains strict typechecking.  If you’re a fan of “Modern C++ Design”, you’ll see that we’re co-opting “Policy based design” for testing purposes.  Policy Based design is the proper name for using templating to solve the bridge pattern in general, of which GDI for testing is a specific application.

I’ll be talking more about this subject in the future, some of its drawbacks and some potential solutions.  Namely, what happens now for the object that needs to create a Foo?  Does it now need to know which Bar it wants Foo to use?  It used to simply be able to create a Foo(), now it has to fulfill a template argument.  Luckily, with some template tricks, we can use functional techniques to make this not the case.  I’d also like to discuss the strengths GDI has over ODI, namely, that it’s use of types falls far closer to “Duck Typing” found in languages like Python, but unlike Python, we still keep strict typechecking.  Finally, I’d also like to talk about some specific C++ strengths that good templating and use of RAII have in the relm of unit testing.

July 20, 2008 Posted by | C++, Software Design | , , , | 7 Comments