Jeremy’s Second Law of TDD: Push, Don’t Pull

Laws of TDD is probably something that should be written by someone with more authority in the community, but I’ve got a blog and I thought of it first, so here goes. I’ll expound on each of these at some point in the misty future, but just for fun here is Jeremy’s Laws of Test Driven Development (I’m certainly not claiming any kind of originality here. Some of these rules predate TDD anyway).

And the overriding “Zeroeth Law” is “If code is hard to test, change it.”

We’re told that the key to safe lifting is to “Push, Don’t Pull.” Pushing gives you more control over a load, greater leverage, and it is safer and easier for your back. We can apply the same principle to software development to create code more efficiently. The goal of “Push, Don’t Pull” is threefold:

Making unit tests easier to setup.

Greater chance of reusing code because of the shorter “tail.”

Looser coupling because functionality is isolated from its configuration and/or data store

“I don’t care how good you think your design is. If I can’t walk in and write a test for an arbitrary method of yours in five minutes its not as good as you think it is, and whether you know it or not, you’re paying a price for it.”

In many ways I think testability is the ultimate test of code and design quality in the small. If a class is easy to test it’s often because its dependencies are minimized or at least loosely coupled. A class or method that is hard to unit test is often indicative of a coupling problem. So back to the Michael Feathers quote, let’s talk about how to make unit tests easy to setup and execute. The easiest test to write is a state-based test where you can easily create the test inputs inside the unit test, execute the code, and verify the results without any external environment setup. Interaction tests are good too, as long as you can keep the mock object setup to a reasonable level. In both cases you’re pushing the data and any dependencies into the class or method being tested inside the test. Much more difficult is a class that “pulls” data, configuration, or dependencies for itself. To test this code you often have to do much more setup work to get the class to function in a test harness. Even worse is the possibility that the test probably depends on data that is external to the test. Understanding a test can be much more difficult if you have to “ALT-TAB” between a sql script, a web.config file, and the test fixture class to relate the inputs of the test to the expected outcome.

Here’s an example of changing “pull” to “push.” We have some code in our system we inherited that is responsible for translating an older flat file format to a new industry standard hierarchical xml format. It’s obviously a vital piece of code in the system that has to be rock solid with tests. There’s a large number of permutations of data that require test scenarios. I’ve also wanted to reuse the code in a couple other situations but I couldn’t easily do it because the translator code “pulls” too much stuff from the database and it’s coupled to a singleton deep in the bowels. The code is difficult to test because there is all of the extra environment setup necessary to run the translation, both in terms of the database state and configuration around the data access code. My answer, when we get around to it, is to refactor the translation code so that its data needs are pushed into the constructor function. The dependency on the singleton can probably be eliminated and moved to an Observer pattern class that will also be injected into the translator class. Once we get to the point where the translation code is given everything it needs to function, that code will be much easier to test and reuse in different situations because it no longer depends on so many other application services. We will be able to completely unit test the translation code without ever involving a database.

When is Now?

Scott Bellware and I had a conversation at the Austin Code Camp about testing date sensitive business rules. It’s something we take for granted, but the call to DateTime.Now is a tight coupling to the system clock. Say you want to create a static set of test data that should exercise a set of business validations against the Invoice object below. The test data might be stored in a flat file (we’re talking testers here), an xml file, or database tables. The point being that the dates in the test data are static. In order for the tests to function the same way going forward we need a way to fake the system clock to make the test behave like the current date is the day the test was created. You could fiddle with the system clock, but that’ll make the tests harder to run. An easy solution is to push in the “Now” time into the OverdueInvoiceProcessor.ProcessOverdueInvoices(DateTime) method like the code below. I’ve used this technique before to great effect, but there’s another approach at the very bottom of the post that I like better now.*

publicclass Invoice

{

private DateTime _invoiceDate;

privatestring _invoiceNumber;

public Invoice(DateTime invoiceDate, string invoiceNumber)

{

_invoiceDate = invoiceDate;

_invoiceNumber = invoiceNumber;

}

public DateTime InvoiceDate

{

get { return _invoiceDate; }

set { _invoiceDate = value; }

}

publicstring InvoiceNumber

{

get { return _invoiceNumber; }

set { _invoiceNumber = value; }

}

}

publicclass OverdueInvoiceProcessor

{

publicvoid ProcessOverdueInvoices(DateTime nowTime)

{

// do stuff

}

}

publicclass OverdueInvoiceProcessorTester

{

[Test]

publicvoid ProcessOverdueInvoices()

{

setupTestData();

setupExpectations();

OverdueInvoiceProcessor processor = new OverdueInvoiceProcessor();

processor.ProcessOverdueInvoices(new DateTime(2006,3,1));

verifyTestResults();

}

}

Dependency Injection

Dependency Injection is a common stratagem for creating testable code. Most classes will depend on other classes to perform other actions or gather information. Typically a class has created its own dependencies when it has needed them. The call to the “new Dependency()” constructor function of a concrete class is a hidden form of tight coupling. If the dependency is something that is hard to test against, or you need looser coupling between the server and client, you’ll want to push in the dependency object with some sort of Dependency Injection.

Here’s a class called Client that uses ServiceProvider within its DoSomething() method. In this incarnation, Client cannot function at all unless the ServiceProvider class is completely configured with all of its dependencies.

publicclass ServiceProvider

{

publicvoid ProvideService()

{

// Provide the Service

}

}

publicclass Client

{

publicvoid DoSomething()

{

// Needs a ServerProvider, so it just creates one as its needed

ServiceProvider provider = new ServiceProvider();

provider.ProvideService();

}

}

Here’s the same class, but this time use Dependency Injection to “push” in an IServiceProvider argument to its constructor function. Client simply executes with the IServiceProvider member that it is handed. The IServerProvider could be a mock object, a stub, the original ServiceProvider, or some totally new implementation of IServiceProvider. Simply by inverting the control over dependency location we’ve greatly increased the testability and potential reuse for the Client class.

publicinterface IServiceProvider

{

void ProvideService();

}

publicclass Client

{

privatereadonly IServiceProvider _provider;

// Client is not responsible for instantiating an instance of IServerProvider

// Verify the expected interactions between Client and IServiceProvider

mocks.VerifyAll();

}

}

Use the Lowly Builder Pattern

Builder Pattern – “Separate the construction of a complex object from its representation so that the same construction process can create different representations.”

I’m not entirely sure what the original GoF definition means, but the Builder design pattern is a simple and effective way to isolate logic from the mucky details of configuration and persistence. Think of it this way, when a rock band like Aerosmith is playing a concert they don’t set up the sound stage, unload the instruments, and plug everything together. The roadies and the concert crews put all of the stage and equipment together. Aerosmith just has to swoop in, pick up the instruments that are waiting**, and play the show. A Builder class is like the concert crew. The Builder’s only job is to put together everything that another class needs in order to do its work. The great advantage of using a Builder pattern is to isolate business logic away from logistical code. We can concentrate on making the Aerosmith classes work first and get the desired functionality working, then create some roadie classes to handle the logistics later.

Here’s an example that’s taken from work my team did last year to rewrite a custom rules engine component. We had to work a couple months with the legacy component a little while and ran into some significant trouble:

The input data had to be put into the database. The rules engine absolutely could not run except by pulling information from the database. The database tables in question had a lot of referential integrity. The overhead cost of setting up test data was substantial.

The rules had to be placed in a SOAP serialized xml file that the rules engine expected to be at a certain absolute path.

There was no way to programmatically configure rules and test data inside the test harness.

There was a large number of permutations of rule configuration and test data that needed to be executed. By forcing us to load up test data in a database and create and move around separate rules configuration files (that weren’t human readable) around made for a tremendous amount of friction in development. When we built the replacement we were able to dramatically improve this situation by separating configuration away from the basic processing engine. The processing engine is given the correct rule objects and data. All it has to do is execute the rules and coordinate the resulting actions. All services are attached through either Dependency Injection or a Service Locator, so it’s relatively easy to substitute mock or stub objects in testing.

Let’s say your building a system to automate the fulfillment of drug prescriptions. When a prescription order is made a series of Event-Condition-Action rules need to be executed to determine actions to take based on the patient’s medical history, prescription, and insurance coverage. Here’s a “before” skeleton of the implementation that could be difficult test. The prescriptions to examine have to be pulled from the database. The rule objects are assembled from configuration of some sort.

publicclass Patient

{

publicstring PatientId;

public DataSet MedicalHistory;

}

publicclass Prescription

{

publicstring Id;

publicstring PatientId;

publicstring PrescriptionType;

}

// Interface for the prescription rules

publicinterface IPrescriptionHandler

{

void ProcessPrescription(Prescription prescription, Patient patient);

}

///<summary>

/// The initial version that “Pulls” rules and data as it needs it inside the processing

/// This version is much more difficult to test because of the tight coupling with

/// the database and the rules configuration

///</summary>

publicclass PrescriptionRulesEngine1

{

publicvoid ProcessPrescriptions(string prescriptionId)

{

// Fetch the Prescription object from the persisted database data

Prescription prescription = fetchPrescription(prescriptionId);

// Fetch the Patient object from the persisted database data

Patient patient = fetchPatient(prescription.PatientId);

// Query the database for a list of all the IPrescriptionHandler objects that handle

Now, here’s a second implementation that follows the “Push, Don’t Pull” law. In this version the rules engine accepts an array of IPrescriptionHandler objects in the constructor and works on the Prescription and Patient objects passed into the ProcessPrescription() method. This version makes new rules far simpler to test because you can create an instance of an IPrescriptionHandler rule object and the input data completely inside of an NUnit test fixture class and validate the results.

publicclass PrescriptionRulesEngine2

{

privatereadonly IPrescriptionHandler[] _handlers;

// The IPrescriptionHandler[] array is pushed in through the constructor

public PrescriptionRulesEngine2(IPrescriptionHandler[] handlers)

{

_handlers = handlers;

}

// All the Prescription and Patient data is pushed in through the method

Configuration & Persistence Last

One of the pieces of advice I try to give to people that are new to software design is to concentrate on creating functionality first, and worry about configuration second. Let the business functionality drive the need for configuration. Trying to create the configuration, or persistence for that matter, at the same time as the business logic can just cloud the issue. Focus on one responsibility at a time.

* There’s an easier alternative for date sensitive testing that might be more intention revealing anyway. We have a lot of business rules that are date sensitive like “Invoice shall be rejected if older than # days.” Inside of unit tests you just set up test data by saying “DateTime invoiceDate = DateTime.Now.AddDays(-30).” In our FitNesse acceptance tests we’ve coded the fixtures to translate “(today+-#)” into the date relative to the current time as the test is executed.

InvoiceFixture

Invoice Date

Invoice Start Date

(today-5)

(today)

(today-30)

(today+1)

**Here’s a story for you Austinites out there, when my wife and I first moved to Austin I begged her to go see Billie Joe Shaver play at the Saxon Pub. Malford Milligan (Storyville lead singer) was tagging along just to help the band carry in their sound equipment. I’m betting Aerosmith doesn’t have to do that anymore. It was a hell of a show by the way. RIP, Eddy.

About Jeremy Miller

Jeremy is the Chief Software Architect at Dovetail Software, the coolest ISV in Austin. Jeremy began his IT career writing "Shadow IT" applications to automate his engineering documentation, then wandered into software development because it looked like more fun. Jeremy is the author of the open source StructureMap tool for Dependency Injection with .Net, StoryTeller for supercharged acceptance testing in .Net, and one of the principal developers behind FubuMVC. Jeremy's thoughts on all things software can be found at The Shade Tree Developer at http://codebetter.com/jeremymiller.

I wouldn’t make any hard and fast rule about reducing dependencies, but yes, the more you can the easier things will be to test and change in the future.

Mario,

So true.

Jeremy

Sheldonp

I love the first two in the series. Can’t wait for the next one!

http://bubbler.net/outlaw/blog mario contestabile

Couldn’t agree more. I’d have to add, get ‘buy in’.
Buy-in from the managers, and the other developers.

http://david_DOT_a_DOT_r_DOT_kemp_HAT_gmail_DOT_com_REMOVE_DOT_ David Kemp

Nice work.

I need to check reread GoF + Fowler’s PEAA, but the Gateway acts like a Facade for service?

I’ve picked up your blog recently, in conjunction with reading Head First Design Patterns (this is the best Design Patterns book I’ve read, even if there is a bit Java specific code in there), and it’s all starting to make sense.

Basically, you’re re-enforcing the “program to interfaces, not objects” rule, and using builder and strategy patterns to create systems with very low levels of coupling? And of course, because everything’s very flexible, you can easily test stuff with mocks, etc, etc.

I think there’s one example in Head First Design Patterns that hammers home just how dependant things can get. Consider: