Test Driven Design using mocks- Lessons Learnt (Part 2)

This is a follow up to my previous post. In this somewhat contrived example we are building a point of sale system and there is a requirement to print out a receipt for a sale, which includes item details, total taxes and the total amount due.
Using Rinho mocks Here is the first test I wrote initially, which drove out the need
for a Renderer role, whose responsibility is to render the contents of the receipt
onto an output device

[TestFixture]
public class SalesTests
{
private MockRepository mockery;

[SetUp]
public void BeforeTest()
{
mockery = new MockRepository();
}

[TearDown]
public void AfterTest()
{
mockery.VerifyAll();
}

[Test]
public void ShouldbeAbleToPrintReceiptForASaleWithNoItems()
{
var sale = new Sale();
var renderer = mockery.StrictMock<IRender>();
renderer.Render(”Total Taxes: 0.00 \n Total: 0.00″);
mockery.ReplayAll();
sale.PrintReceiptOn(renderer);

}
}
the implementation needed to pass the above test was as follows

public interface Renderer{
void render(String s);
}
public class Sale {

public void PrintReceiptOn(IRender renderer)
{
renderer.Render(”Total Taxes: 0.00 \n Total: 0.00″);
}

By driving the design test first I was able to discover the need for an object to play the Renderer role, using mocks I was able to drive out interface for the Renderer role.
But I also realised later the above test was brittle and over specified, because
the test was very tightly coupled to the implementation, because the conversation between the objects was not at the right level.
for instance if I changed the implementation of printReceiptOn on the Sale object to

public void PrintReceiptOn(IRender renderer)
{

renderer.Render(”Total Taxes: 0.00″);
renderer.Render(”Total: “);
renderer.Render(”0.00″);
}

The test will break (because the test specifies the Render message be sent to the renderer only once with a specific argument) although the implementation is
quite valid. So the test is tightly coupled to the implementation
Now we could try addressing the symptom by defining a looser constraint on the test as shown below

[Test]
public void ShouldbeAbleToPrintReceiptForASaleWithNoItems()
{
var sale = new Sale();
var renderer = mockery.StrictMock<IRender>();
renderer.Render(”Total: 0.00″);
LastCall.Repeat.AtLeastOnce().IgnoreArguments();
mockery.ReplayAll();
sale.PrintReceiptOn(renderer);

With the above either of my previous implementation would make the
test pass. however it doesn’t test the right data was being rendered.

To ensure that the right data was being rendered
We could write a state-based using a collecting stub to verify the data being
rendered is correct as shown below
[Test]

public void VerifyReceiptContentsForSaleWithNoItems() {
TestRenderer renderingDevice = new TestRenderer();
sale.printReceiptOn(renderingDevice);
Assert.assertEquals(”Total Taxes: 0.00 \n Total: 0.00″,
renderingDevice.GetContents());

}

where TestRenderer is a collecting stub which is implemented as follows

public class TestRenderer : IRenderer {
private String contents;

public void Render(String s) {
contents += s;
}
public String GetContents() {
return contents;
}
}
At this point I was questioning the usefulness of a mock, it seemed I was better off using a state based test and using a colleting stub to verify. The brittleness of our initial interaction based test, indicated an underlying design issue, interaction was not specified at the right level. The trick here is to design interactions that are meaningful to the calling object, this leads to interface discovery, (and this is one of the reasons why you should not mock 3rd party API’s). Now Render(string s) is not a meaningful message to the Sale object to be sending to the Renderer, the Sale object knows about items, taxes and total so What would have been more a meaningful interaction (conversation ) between the Sale object and Renderer would be to specify the interaction in terms of taxes, items and total, as shown below.

[Test]
public void ShouldbeAbleToPrintReceiptOnAPrinterForSaleWithNoItems()
{
renderer.RenderTaxes(0.0m);
renderer.RenderTotal(0.0m);
mockery.ReplayAll();
saleUnderTest.PrintReceiptOn(printer);
}
public interface Renderer {
void RenderTotal(decimal total);
void RenderTaxes(decimal taxes);
}

the following is now the implementation of the PrintReceiptOn method of the Sale Object

public void PrintReceiptOn(IRender renderer)
{

renderer.RenderTaxes(totalTaxes);
renderer.RenderTotal(total);
}
This is where mock objects are so useful as they aid in the discovery of interfaces and quickly give us feedback in the form of brittle tests when interactions between objects are poorly designed.

Test Driven Design using mocks – Lessons learnt (Part 1)

Lesson 1 – “Specify conversations between objects an abstract enough level”

A common complaint with using mock objects is that interaction based tests ties your tests to the implementation details of the production code and interaction based tests are tracking the implementation of the method you’re testing. I felt this many times previously, every time I refactored my production code some of my tests seem to break even though, functionality of the object remained the same. Often mocks and interaction based testing are blamed for brittle tests. I have come to realize any brittleness exposed by interaction based tests is just a symptom of an over specified test or their is an underlying design issue because of a weak interaction model.

Interaction tests will be brittle and tied to the implementation if you dont specify interactions at the right level, and your tests will quickly let you know. After spending time doing some development in the Smalltalk world, i rediscovered that OO is all about message passing (object interactions). So a good OO model must have a good interaction model, with this in mind i have come to realize that the key to interaction based testing is specifying interactions (or conversations) between an object and its collaborators at the right level. An object should tell its collaborator what it should get done and not how it should do it. This drives us not to include even a hint of implementation detail when designing our interactions between the object under test and it collaborator, this forces us to create collaborator interface at an abstract enough so that no implementation details gets in the way, this leads to what is often called interface discovery of the collaborating objects, and is a great exploratory way to design the interface of collaborators and distribute responsibilities between objects and mocks are a vital tool to do this. This is what Steve Freeman and Nat Pryce have been telling us all along, but its only now I’m starting to understand this. However i also learnt not to use mocks everywhere, generally if I cannot model interactions between an object and its collaborator at an abstract enough level that made sense to the calling objects domain, it generally means i’m unable to define a clear role interface for the collaborating object, then in this case i would not use mocks at all, rather I tend to use a real object or a stub and test a cluster of objects together.
So what do I mean by “Specifying conversations between objects an abstract level”. I will try explaining by giving an example in the next post

My journey to Smalltalk

Ever since I started my professional career as a software developer back in 2002, nearly all of my development was done using C sharp and .NET framework with a bit of Java here and there. However while studying software engineering at University of Sydney 90% of my work was done on unix machines, I was taught object oriented programming in my first year, and thankfully we didn’t get introduced to OO by learning C++ or Java but a language called Blue (it was first developed by the Basser Computer Science department at the University of Sydney to teach students OO concepts) . Blue was not just a programming language but was a programming environment, which allowed interactive manipulation of classes and their relationship to each other graphically or textually. This allowed me to visualize a group of instantiated objects whose state was encapsulated and only way the objects performed anything was by collaborating with each other sending messages to each other to perform a task.

As I learned mainstream languages like C++ and Java. The idea of objects sending messages was blurred by multiple inheritance, classes and types. Throughout the years as I read books, researched and experimented with different ideas, I noticed Smalltalk being reference numerous times in every book OO book and every time Objects, XP and TDD were discussed. Xp and TDD were all conceived in the Smalltalk community and some of my favorite authors like Kent Beck, Rebecca Wriffs-Brock and the numerous speakers at OOPSLA every year all had a Smalltalk background. So about a year ago I decided to check out and learn this Smalltalk thing. It was a steep learning curve in the beginning (especially getting used to the idea of not working with source files) it was a big paradigm shift but it the best thing I did, there such a long history and wealth of experience in the Smalltalk community. Just browsing through code base in the standard squeak Smalltalk image, studying the wonderfully crafted code which was refined and polished by master Smalltalk craftsman over the last 25 years has improved my understanding of good OO design and also increased my productivity in my day job using C sharp and .NET. After experiencing Smalltalk and programming with “live objects”, going back to C sharp or java seems a little dull at times they are not nearly as expressive as Smalltalk. While learning squeak Smalltalk and as I immersed myself into the Smalltalk culture, I stumbled across Seaside a framework to create web based applications entirely in Smalltalk. Seaside kind of blew my mind, I have dabbled with Rails a bit and it is very clean and can be very productive, but Seaside takes web based development to a whole new level I never seen highly complex web based applications developed this way. Well it wasn’t long before I discovered GemStone/S which is not just an OO database but a powerful object server based on Smalltalk (more on this in another post). Through Smalltalk I rediscovered just how powerful it is to think in terms of objects not classes and just be able to send any message to *any* object that can understand that message. Now I realize that OO is more about message passing and actually very little to do with classes, inheritance or types. I found this quote by Allan Kay where he states what OO is all about.

“OOP to me means only messaging, local retention and protection and hiding of state-process, and extreme late-binding of all things. It can be done in Smalltalk and in LISP. There are possibly other systems in which this is possible, but I’m not aware of them.” – Alan Kay creator of Smalltalk

Object Persistence ??

In software development, programming only represents half the problem, the other problem is storing and sharing data across users and other programs. The Object oriented paradigm expands the meaning of “data”. Object contains methods, complex data structures and references to other objects. This can’t be easily stored in a relational Database.

Although it is possible to store objects in a relational database, we can’t overlook the underlying conceptual differences between the relational and object paradigm. This is common know as the impedance mismatch .

we can define objects in terms of classes and create hierarchies of these classes, now to effectively store objects, a database must be able store inheritance hierarchies and create instances of these classes using this information. Relational database were never designed to handle hierarchical structures like this. As Developers we spend a lot of time to work around these limitations to try and make it all fit, knowing very well there is an obvious  underlying mismatch. Let take a very trivial example, suppose we have an Address class which was mapped to an Address Table. Now suppose there was a requirement to handle new types of address which contained an additional field. On the object level we could create a subclass of Address and define an extra variable to hold this additional field. Now on the relational database we would typically create another table to hold this additional information with a link to the Address table. Now this requires construction an object from multiple tables, now as the object structure get complex this can be very time consuming.

Most object oriented designs contain composite objects and usually there are complex patterns of interaction between these objects. Objects hold reference to other objects, to allow fast navigational access. Relational databases on the other hand can also handle these nested structures but they have no references so navigational access is not possible but they have is associative access which based on matching data, this process is very slow and depending on the complexity of the nested object structures, this can be a time consuming process. A study done by the US navy showed relational database are 100 to 1000 times slower than a database that can provide navigational access.

As mentioned before the object paradigm expands the meaning of “data”, one of the fundamental characteristics of Object Oriented design is encapsulation. Objects contain methods as well as data, this means storing methods and data as one package and maintain cohesion between the two. Generally relational database cannot support this, relational databases have stored procedures but this is usually programmed using Sql (Original intent of SQL was never intended for programming but to be used by the end user). This is always different to the programming language used to implement the objects.

In my opinion relational database introduces barriers to object thinking, objects allows us to think in terms of real objects such as customer, products, items. When they are stored in a relational database they are dissembled into different tables. rather than thinking about the domain model, we try to design our object model so they can be chopped up later into some low level data which bears little resemblance to the original object just so they can some how fit into a relational database. This is the same as having to disassemble your car every time you wanted to park it in your garage. Not only that you stored each part in a different garage, you have a garage where every body put there car wheels, another garage where every one stored their car body. And when you want to use your car again in the morning, you had to go to each garage identify the part that belong to your car, then assemble it before you can drive your car again, how painfully inefficient, but this is essentially what happened when we store Objects in a relational database.

O/R mapping are great for some problems (check out GLORP) but really they don’t solve the underlying impedance mismatch problem, it might insulate the mapping from the developer to a certain extent, but really you still disassembling your car before parking in the garage, its just being done by someone else.

Can a Object Oriented Database provide the perfect solution ?

Object Oriented or Class Oriented Design?

Its been over 40 years since object orentation as a programming pradigm started in Norway when Kristen Nygaard and Ole-Johan Dahl invented the language Simula . Now a days most software is describe their work using some sort of object vocabulary and or use an OO language. However the ubiquity of object oriented languages does not mean, in experience most developers aren’t getting the full leverage out of object technology. Object orientation is a programming paradigm you can design object oriented software and implement it using almost any programming language, of course some languages offer you more support than others, conversly you can implement your software with a very non object oriented implemetation using an ‘Object Oriented Language’ such C#, Java or even Smalltalk. Object oriented design and object thinking trancends programming languages. So it not the tools or programming language you use to implement the software, but its the way you think about a design. Thinking in objects is the key to leveraging the most out of object technology to create elegantly designed software. Trygve Reenskuag creator of the MVC pattern, and the creator of the OORAM software Engineering Method comments that programming languages are class oriented rather than object oriented, thats why most of us end up thinking and modelling in terms of classes rather than objects. A Class is powerful abstraction to implement objects, but its inadequate for modelling and thinking about objects, because a Class is static, it is defined at build time, objects on the other hand are dynamic.

Objects vs Classes

It’s important to understand the difference between a class and an objects, I remember when I was at university learning C++ people used the term class and objects interchagably, it is key to distintguish between the two. A class can be viewed as template that defines a set of characteristics and behaviours an object will have, a class is also a factory which creates specific instances of objects that have these general characteristics and behaviours. In languages like Smalltalk a class is an object, that is responsible for creating instances of objects with a particular class of behaviours and charateristics.

Similarly it is important to distinguish between ‘Object thinking’ and ‘Class thinking’ when desgning Object Oriented software. Thinking and modelling a solution to a problem by thinking in terms of various classes rather than thinking of a group of objects working together, more often that not results in a implementation that is inelegant and rigid.

Object Thinking

David West has written an excellent book titled “Object Thinking” (I highly recommend this book to every developer). Thinking in terms of classes, focuses our attention on the solution space rather than the problem space. A class is very static by thinking in terms of classes our solution tends to be static and rigid, objects on the other hand are dynamic, by thinking in Objects we let the problem define our solution, which leads to modelling a more natural and elegant solution. Think about an object as “A virtual person that is capable of performing certain tasks. who has access to all the knowledge and resources required to complete its assigned tasks”. What we will have is a cooperating community of virtual persons interacting with each other to solve a problem. Thinking in terms of objects will lead to a closer match between your object model and the business model (the enterprise domain). Thinking in objects also helps us find the naturally occurring divisions and classifications in the problem space.

Consider the following example, there is a Club that has different types of members, GoldMember, SilverMember and StandardMember, all members have a name, address, date of birth etc, but each type of member has a different discount Rate.

thinking in terms of classes we usually come up with the following implementation, using class inheritance

Class Diagram

The above is a workable solution, but its kind of rigid. Suppose we have an object which is an instance of class SilverMember, think back to the ‘Object as a Person’ metaphor. suppose this virtual person (ie this object which is instance of SilverMember) wants to upgrade to a gold membership. What happends now ? with the above implementation you would have to create a new instance of class GoldMember. Class are static defined at build time, objects on the other had are dynamic, that is why it is important to think in terms of objects and the various Roles they play when modelling. In the real world all you would do is get a new gold membership card or something like that.

thinking along these lines we could come up with the following implemetation

Implemetation Using Object Composition

in this implementation we have a solution that uses object composition, a member object has a Membership object. In the above solution it trival to plugin different membership objects into the member object. so if a SliverMember wants to upgrade to a GoldMembership all we do is set member Objects membership property to an instance of GoldMemberShip and discard its old SiverMembership.

The above solution is example of the strategy pattern in action. Thinking in terms of objects and modelling in terms of the Roles the objects play, leads to a elegant solution.

To conclude object orientation is a pradigm, its a way of thinking. A Class is great and a powerful abstraction for the implementation of objects, so most OO programming languages are class oriented because they are all about implemention of computer programs. But for modelling and designing object oriented solutions it is important we think in term of objects and the Roles the objects play. Trygve Reenskaug has written numerous articles and an excellent book on role modelling