On Friday we got to the point where the FX buiness logic code was suitably decoupled from the display logic that we could write our first test for the business logic. In the words of Homer Simpson, “Woo hoo!”.
Test one was a simple one; can we construct the FX ’live point’ object. After adding a few interfaces and mocking up a service provider or two we could.
The object uses two-stage construction; not ideal, but the code doesn’t use exceptions yet. The first stage creates the point itself and the second stage wires it up to the live data. The second stage can fail if we’re asking for a point for which there is no live data, or for which the live data doesn’t extend out far enough in the future.
Writing a test for the second stage of construction was more complex. Most of the parameters passed into the function should have actually gone into the constructor, they’re constant for the life of the point and a point can only be constructed and made live once. Not the best of design, but once we have some tests we can look at dealing with that side of things. Whilst writing the second test we refactored the first test and the construction code to move these items back to the constructor.
Now the function needed a live data provider. We had one, but only a concrete class. We slipped in an interface, decoupled the FX code from the Reuters code and created a mock data provider. We then chased concrete Reuters classes through the FX code until they were all replaced by interfaces and we had a very basic set of mock live data classes.
The decoupling process was quite interesting. Step one was to locate a concrete class that we needed to mock up. Slip in an interface with no methods and have the things that needed the service accept the interface and the thing that provides the service derive from it. Recompile and the compiler tells you all the methods that need to be in the interface. Move all of these to the interface, and repeat for the next concrete class.
This seemed to be a particularly painless process and one that left us with interfaces that provided only the functionality that the clients required. It acted as a neat way of seperating the code that the Reuters library needed to manage the interactions between the objects with the code that the clients of the library used.
So now we had a set of simple, stubbed out, mock live data classes and an FX engine that used them. We could wire the FX code to the mock objects and watch the test fail as the FX code asked the data provider for live data that it knew nothing about.
We had a failing test, must be time to go home for the weekend.