Do mocks create high coupling ?
Posted: October 10, 2011 Filed under: Mock Objects, Test Driven Design | Tags: Mock Objects, TDD 2 Comments »In a recent discussion with a colleague, he bought up the age old myth that mock objects are bad because they cause brittle tests and pointed me to this post. My view is if using mock objects are causing brittle tests it is a hint that there is a issue with the design of objects collaborating, which needs to be addressed. Mock object are a great tool that aid in the design of OO systems if you subscribe the “mystical view” of object oriented programming as described by these books RDD and GOOS . Ralph Johnson notes “The mystical view is that an OO system is one that is built out of objects that communicate by sending messages to each other, and computation is the messages flying from object to object.”
lets start by looking at the example in this post
module Codebreaker
describe Game do
describe "#start" do
it "sends a welcome message" do
output = double('output')
game = Game.new(output)
output.should_receive(:puts).with('Welcome to Codebreaker!')
game.start
end
it "prompts for the first guess"
end
end
end
with implementation code as show below.
module Codebreaker
class Game
def initialize(output)
@output = output
end
def start
@output.puts("Welcome to Codebreaker!")
end
end
end
While it very clear in the above example the implementation code simply duplicate the test code, and severely inhibit any re factoring with out breaking the test code. As the author of the blog post points out any of the following implementations are valid but yet they would break the test
@output.write("Welcome to Codebreaker!\n")
@output.print("Welcome to Codebreaker!\n")
"Welcome to Codebreaker!".split.each{|c| output.write(c)}; output.write "\n"
@output << "Welcome to Codebreaker!\n"
The key here is to “listen to the test”, there is duplication in test and implementation, the test is highlighting a serious flaw in the inter-object protocol. One of the things I picked up over the years in various discussions at London Xtreme Tuesday group is that an object should send messages to its collaborator in terms of its domain language. In the example above an instance of the Game object sends the message
:puts
to its collaborator. now :puts is a meaningless message in terms of the Game. With the mystical style of OO the domain model is in the message flying between the object.
One way to fix the above code is as following. start with an end-to-end test to verify the end result for a given scenario.
the unit test would be as follows
module Codebreaker
describe Game do
describe "#start" do
it "notifies game has started" do
gameEventListener= double('gameEventlistener')
game = Game.new(gameEventListener)
gameEventListener.should_receive(:new_game_started)
game.start
end
it "prompts for the first guess"
end
end
end
The key thing to note here is that the message :new_game_started is meaningful in terms of the Game objects domain. The role (gameEvenListener) of its collaborator is now made explicit in the test. We can now have an implementation of this role with write out the appropriate welcome message when it receives :new_game_started . While this is very simplistic example and may not seem like there is a huge impact on example, In larger systems I find well designed inter-object object protocols leads to simpler flexible system where behaviour can easily change by composing different objects.
In chapter 6 of the RDD book the authors describe different control styles in a system. I find that mock objects is a tool that guides our design to a “delegated control style” , one of the key characteristic of this style is
“Dialogs between objects are at higher-level.Collaborations between a coordinator and the objects it coordinates are typically higher-level requests for work and not simple requests to store or retrieve data. Communications are more abstract and more powerful. Instead of asking objects to do small chores or divulge small bits of information, coordinators typically delegate larger-grained requests.”
At the same time if we distribute responsibilities across too many different objects we have the following side effects “Complicated collaborations between delegator and delegates. This can happen when not enough context is passed along with a delegated request. Lots of collaborations but not much work getting done.”
When using mock object the test will be very sensitive to these issues and will highlight these facts by being tightly coupled to implementation details of the object or by awkward tests
To summarize the mains points are we
- need to understand the philosophies and ideas of OO to effectively use and appreciate mock objects
- Using mock object is a great feedback tool that can be used to design high level dialogues between objects, brittle tests is usually an indication that the object design needs to be reviewed.
- in an OO system the domain model is in fact in the messages sent between objects.
- Object must send messages to it peers in terms of its domain language.
Design for test ?
Posted: August 14, 2009 Filed under: Uncategorized Leave a comment »Rebecca wrifs-brock recent article discusses this topic here. its an interesting read
Designing inter-object protocols using mocks
Posted: June 8, 2009 Filed under: Mock Objects, Object Oriented Design, Test Driven Design | Tags: Arrange Act Assert, Mock Objects, NMock, Test Driven Design 2 Comments »The intent of my recent paper, was to demonstrate how mock objects could be used to discover roles, and design the communication protocols between objects. The following content did not make it to the final version, I think these are important points so i will describe them here.
Distinguish between an Object’s Internals and its Peers
It is important to distinguish what the internals of an object are and who are its peers that it communicates with. An object’s internals are usually created and used within an object. In my example the fact that the Register object collaborates with the Sale object to calculate the receipt total is hidden. Peer objects, on the other hand, aren’t hidden inside the object, they are a passed in to the object, either through the constructor as a dependency or through a setter (if the peer object is a policy or notification object).
All interactions internal to an object should be hidden from the client code that uses the object; likewise a unit test should not be concerned with the internal details of the object under test.
Exposing an objects internals details to simply test every aspect of a class in pure isolation, causes the tests to be overly coupled to the implementation details of the object. You will find tests using mock objects highlight these design issues very quickly, one hint is when you find that the production code, simply mirrors the expectations you wrote in the test code, this obviously makes tests very brittle since they overly coupled to the implementation details of the object under test.
This could be addressed by changing the behavior of the mock framework to ignore all calls between the object under test and its collaborator unless explicitly specified. However this does not address the underlying weakness in the design of the protocol between the object under test and it collaborators, it fact it simply hides all complex inter-object protocols.
Nat Pryce coined the phrase “A composite object should be simpler than the sum of its parts.” An object should provide a simpler API to its clients, rather than simply exposing all its internal objects through its API. I find this is a good heuristic to follow when deciding what should be internal to an object and what its peers should be. On the other hand we should ensure we are not hiding the wrong information inside an object. Well-designed objects should be context independent and not tied to its environment; objects tightly coupled to its environment will be difficult to instantiate in a unit test. I find the rapid feedback provided by tests is invaluable when designing objects.
Why did I chose to use NMock ?
A lot of people ask me why i chose NMock, for this introductory article, I felt NMock 2 is the best choice of API, because it works best within the context of the article. It has an expectation-based API, which makes designing object communication the focus of testing. Its expectation API acts as a domain specific embedded language that clearly, precisely, and declaratively describes object communication. I also find that NMock2 provides a highly detailed explanation of what has failed, which allows for quick error diagnosis and resolution.
I’m sure many people will have different opinions on this but I have avoided using mock frameworks that use the popular Arrange, Act, Assert (AAA) style because I find that it does not get you started off by thinking about the contracts or communication protocols between objects. With AAA-style mocks I find it’s easy to overlook design flaws in your inter-object communication.
The main drawback of NMock is the use of strings to identify expected methods makes refactoring harder. This becomes less of an issue when a code based is designed around well-defined roles and responsibilities, containing narrow role based interfaces, which are used more locally.
Why GemStone/S
Posted: November 21, 2008 Filed under: Smalltalk, Uncategorized | Tags: GemStone/S, Object Oriented Design, Object Persistance, Ruby, Smalltalk 1 Comment »Most business software systems are built using the object oriented paradigm, one of the key concepts of OO is encapsulation and that the data and behavior be packaged together and the distinction between the two be hidden within the object. In every company and client i have worked for one of the biggest assumptions made is the idea that programs and data should be stored separately, storing data separately violates encapsulation at the most fundamental level and it greatly limits the adaptivity of a system. we aren’t able to completely leverage all the benefits of Object Orientation.
“However, doing encapsulation right is a commitment not just to abstraction of state, but to eliminate state oriented metaphors from programming.” – Alan Kay
Now to eliminate the distinction between databases and programs, we need a technology that seamlessly integrates the capabilities of the programs and storage and multi user capabilities of databases. This is exactly what GemStone/S is, its a Smalltalk dialect, that has object persistance and transactional capabilities baked into the Virtual Machine !. A GemStone/S repository has living objects (there is no seperation between code and data, Code are objects too). GemStone/S is not simply an object oriented database because it not only can stores objects but also can execute them in a muti-user environment. What GemStone/S is, is its a true object server.
So what does this buy us ?
- No more object-relational mapping (no need for ActiveRecord, Hibernate, GLORP like ORM’s)
- Makes the software incredibly adaptable, normally if we change the structure of the data defined in a class, we would also need to modify the structure of the database, mapping files etc to reflect the change, so GemStone/S Eliminates need for the synchronization of code and data, because there is no distinction between the two.
- Objects can evolve as the business needs change, Its quite simply to change the shape of a class in a GemStone/s repository.
- Allows us the ability to create executable business models and objects that cross cut applications, so pure objects can be shared across mutiple applications. The object can expose a specific interface with a set of messages to each application. This way there is a single point of reference for a particular object and also a single point chage for a particular object. (note none of the data is ever exposed to the app, every thing is done through the object interface by sending messages)
- Check out this case study where a large shipping company used GemStone/Smalltalk to create a pure OO solution.
Every DSL ends up being Smalltalk
Posted: October 27, 2008 Filed under: Smalltalk | Tags: Add new tag Leave a comment »“I had this though in my head for a while now. I built an IDE for a DSL, and somewhere toward the end of the first revision I understood something very interesting. My IDE wasn’t actually using the textual representation of the language. The scripts that the user was editing were actually live instances, …….“
Smalltalk a world of living Objects
Posted: June 10, 2008 Filed under: Smalltalk | Tags: Objects, Smalltalk 5 Comments »When I first discovered Smalltalk, it took me a while to get my head around the fact that in image based Smalltalk systems, source code is not written in flat files. Source code in files was so ingrained into my thinking, I had to unlearn and leave a lot of assumptions I have made. In most programming languages programs are written and defined using text files, typically source code is written in text files, using a text editor or an IDE such as Eclipse, IntelliJ or Visual Studio. At this point it just “dead code” in text files, there are no running objects, this is often referred to as compile time. Before a program runs, the runtime environment is created, the program’s source code is parsed, compiled and executed, and when the program finishes the runtime environment is destroyed, so in essence every time a change is made to source code the entire program is created from scratch. Smalltalk is pure object oriented and everything is an object and everything is achieved by sending messages to objects. In Smalltalk we dont use source code in text files to define programs (classes methods etc) instead objects are used to define Smalltalk programs, objects themselves are used to define new classes method etc. Now an object can exist only at runtime, and in Smalltalk everything happens on the fly, there is no such thing as compile time, Smalltalk is a runtime, it is not just a programming language, its a living system, it is a world of “living objects”. This requires a paradigm shift and it often is one of the biggest barriers I find people face when entering into the Smalltalk world. Smalltalk pushes “Object thinking” to another level, but once you push past that barrier you enjoy all the benefits of working with living objects, you can interact with objects, inspect them modify, extended and change them on the fly. This is the main reason why Smalltalk environment have such powerful IDE’s.
So what happens when the smalltalk VM is shut down or not running ? Do the objects then die ?
No. The objects are in a suspended state or go into hibernation and are stored in an image. This is analogous to a VMware image, when you close a vmware image the operating system goes into a suspended state, so the next time the vmware image is loaded to exactly the same state it was before. In Smalltalk objects essentially never die (note objects without any references will be garbage collected), they simply go into a suspended state in the image, in a Squeak Smalltalk image it is very likely some objects are probably 30 years old !
In Smalltalk everything is an object, classes are first class object too, so they can respond to messages just like any other object, so it trivial to create new classes on the fly. The image based system of the Smalltalk might be a stumbling block for people entering into the Smalltalk world but I think this is one of the main things that gives Smalltalk its power, its awesome IDE and the ability to work with live objects makes development so much more productive.
So Smalltalk code doesnt live in files so what happens to version control systems then ?
I do most of my Smalltalk development in Squeak and I use Monticello as the versioning system, in Smalltalk source code itself are represented as objects and are basically modelled as a collection of packages, classes, and methods. Code changes then simply become addition/removal or update of these elements. Since the entire source code are modelled in objects, Smalltalk version control systems have very powerful merge and diff algorithms. The version control systems are language aware and source code changes and history can be tracked down to individual method.
Smalltalk is an amazingly powerful environment, developing in a Smalltalk made me see what incremental development is really about. I guess with GemStone now working on a Ruby VM which is primarily based on the GemStone/S Smalltalk VM, folks from the Ruby world can also experience developing with living objects
Test Driven Design using mocks- Lessons Learnt (Part 2)
Posted: May 28, 2008 Filed under: Mock Objects, Test Driven Design | Tags: interaction based tests, Mock Objects, Test Driven Design 3 Comments »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)
Posted: April 25, 2008 Filed under: Mock Objects, Test Driven Design | Tags: interaction based tests, mock object, Test Driven Design Leave a comment »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
Posted: March 15, 2008 Filed under: Smalltalk | Tags: Seaside, Smalltalk 5 Comments »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 ??
Posted: October 24, 2007 Filed under: Object Oriented Design | Tags: Database, Impedance Mismatch, Object Oriented Database Leave a comment »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 ?