Agile in enterprise legacy software

Series

After building the Golden Master in the previous iteration we are sure that we wont introduce any bugs during our refactoring phase: we built a safety net that will prevent us form falling into the regression trap.

The next refactoring I’m going to practice is Subclass to test followed by replace inheritance with delegation. As you can see here subclass to test is a powerful technique to break dependencies and test only the method we are interested in refactoring , but it’s also considered by some an anti-pattern because the complexity of the code becomes higher and higher making it difficult to apply refactoring techniques later on.

Testing the questions’ initialization

In this exercise I decided to refactor the askQuestion method of the Game class.

The first step in building the test suite is to create a class that inherits from the Game class in order to be able to reach it’s internals without actually making them public.

private class GameForTests : Game
{
}

To test the askQuestions I can tests that it pops the correct questions from the correct category and to make my life a little easier I decided to spy on the values contained by the questions’ linked lists, so the next step was to promote the linked lists to protected and expose them in the test class.

Why should I care?

To test the askQuestion method it would have been enough to stub out the lists instead of checking that they get correctly initialized. I’m doing this extra work because I’m aiming at extracting a class that represents the deck of cards and testing that the lists get initialized correctly will help me testing that the deck class gets correctly initialized too.

Second step: test askQuestion’s behaviour

Looking closer at the method askQuestion I notice that it have one indirect input in the form of a method call to currentCategory, one indirect output as it writes one question to the console and some side effects when it pops the questions from the linked lists.

My goal with the test is to check that for any possible indirect input, the indirect output and the side effect are what I expect them to be: for example if currentCategory returns “Rock”, then the method should write the next rockQuestion to the console and then pop it out of the list.

To do so I want to control the values returned by currentCategory so, first of all I add a public property to GameForTests that I can set during my tests with the value I want currentCategory to return, then I promote the later to protected virtual in order to override it and make it return the value of the new field:

Preparing to extract the class

Now that we have the method tested through “subclass to test”, we want to extract the tested code as a dependency in order to separate the miss-placed behavior. the next move then is to prepare the code to extract a class clearly isolating the parts that could go in the extracted class from those that need to remain.

I start by moving the `Console.WriteLine` calls out of the condition blocks so that the askQuestion first evaluate a temporary string that then gets passed to the indirect output.

And the body of the constructor becomes a call to a method that initializes the deck.

All my tests still pass so I’m good to go;

Extract the Parent class

I then change the Game class so it inherits form a parent class called, you guessed it, GameParent. The purpose of this move is to move all the logic for asking a question out of the game class so it will depend only on a call to a parent method. I still don’t need to change my test.

Yon may notice that it has a protected method called Question that gets a category and returns the question to be asked: This method doesn’t have any indirect inputs nor it has indirect outputs, those remain in the askQuestion method which is now super simple: it retrieves the category, then gets the question form the parent and then sends it to the console.

Extract the dependency

Now that the code for building a deck and retrieving questions form it is isolated inside the parent class we can apply the Replace inheritance with delegation refactoring to break the parent-child dependency.

Making this change requires to first change some tests in order to have them pointing directly to the parent class. This isn’t a breaking change but the Game class looses it’s coverage so I’m also forced to write a new test to be sure that the behavior of the askQuestion method doesn’t change.

I first rename the parent from GameParent to CardDeck and build a child class to test:

As you can see this test doesn’t need to redefine the Console’s output stream as the Question method returns a string and doesn’t have indirect outputs. The new test that I have to write checks that, for any given category, the askQuestion in the Game class sends the question to the console like before:

now that I’m happy with the status of my tests I’m ready to break the inheritance. Now the game class doesn’t inherits from anyone and it has a CardDeck as a private field that gets assigned in the constructor and the ask Question simply calls the Question method of the CardDeck field and it has no clue of how the questions are stored internally in the CardDeck class.

Conclusion

Even if a little bit longer than just asking to ReSharper to extract a class, proceeding with this refactoring gave me the opportunity to make every step in a save and clean way without suddenly breaking the test and having to fix them later. The only time the test got broken was when I needed to change the structure of the code so heavily that I decided to change the test to reflect the behavior that I’m expecting from the change.

What struck me was that at every change it was crystal clear to me what was the next step to be taken in order to improve the code. This doesn’t happen a lot when refactoring code at work when you have less time and have to take shortcuts.

If you liked this article and want more Subscribe here and you wont miss any article.

Like this:

If you have been comdamned to work on old, ugly, unmantained and untested code, then you probably feel the urge from time to time to clean up a little bit and make your life easier. Let’s face it, cleaning up some mess in the code is always fun, until it’s not: until you have to work in the night to fix some bug you introduced in a core feature just because you wanted to clean up the code.

You know there’s a huge risk in every change you make, but you want to work with better code, so you have two options: you either clean it or you leave your job! Leaving a job is slow and painful and you have no guaranties that you are going to land a job which offers better code to work on, so your only choice is to clean up.

But, where to start? How can you minimize the risks? well, we have written a lot about how to handle legacy code (have a look at our Blog series page) and there are some great books that you can read (go to our Resources page). But what if you want to practice and experiment in a safe environment without the risk of breaking your production code? With some luck you can find some User Group near to you that hosts a Legacy Code Retreat but if you are nowhere near a developers meetup like I am you can always find some ugly source code and try to practice by yourself the same excercices they do in the code retreats. And what better code can you use for this purpose than one that was specifically designed to be legacy: just go here, download it and start refactoring.

That’s exactly what I did and I wanted to share the process with you in this series of post so you can compare your approach to that of a fellow programmer.

First iteration

Like every legacy project that’s worth its name, there is not enough information about the code you are going to touch. So the first iteration is about discovering how bad its state is and what’t the whole purpose of the code. If you had time you could try to apply some refactoring techniques trying to minimize the risk of adding bugs. After 45 minutes you had to stop and delete everything you have done so far.

After some analysis I discovered that this game is basically a simplified implementation of the Trivial Pursuit. It’s formed by two classes the Game class that has all the business logic of the game and the GameRunner that it’s basically the main entry point of the program. For some obscure reason the game loop is located in the GameRunner.

After starting the game, the game runner adds three players to the game and then starts the game loop that can be described by these steps:

a player rolls a standard 6 faces dice

based on the result and the player’s current status the player moves or remains in the same spot

A question is asked to the player which responds to the question with 1/9 percent change of getting it wrong

the game continues until there is a winner: the first one to reach 6 points.

I still haven’t been able to understand how does the player gains it’s points.

The code

Exploring the code gives you headache: you cannot understand if it was so badly crafted written for the purpose of the exercises or if JB asked a fifteen years old kid who is trying to learn to program to write it. I have tried to build examples of bad code and was never able to create something so beautifully ugly!

By the way let’s have a look at the code:

The game runner starts instantiating a Game object and then it calls and add method with something that looks like player names.

The method add in fact adds the player name to a list of strings called players then, it looks like it places the player in the first box with zero points, then it returns true (why returning true? what does it means?).

Back to the GameRunner class. In the game loop a random number between 1 and 6 is picked and then this number is passed to the roll method. Here there is some duplication and some business logic difficult understand, for example: if inPenaltyBox for the current player is true and the random number (roll) is not even (why on earth check that something is not even? wasn’t it the same checking that it was odd?) a variable called isGettingOutOfPenaltyBox becomes true.

The askQuestion method checks which category is the player in and pops a question from the question from the queue (smells like bug… what happens if you run out of questions of a certain category? a you get a nice little exception!).

The currentCategory method looks like a really malformed array of strings, but you cannot be sure until you know know how many places there are in the game and which one are actually of “Rock” category, are there some bonus places not considered in this method?

Refactoring

The first thing I would like to address is the players management, there should be a Player class that handles most of the actions on the player, like it’s points or if it’s in a penalty round. Another improvement could be to isolate is the Board itself in a class that knows places and categories for each one. If you then extract a set of classes that represent the deck of cards and move the game loop inside the game class.

The problem is that these entities are spread across multiple methods and extracting requires changing a lot of places, so it would be better to first have a comprehensive suite of automated tests.

Simple things first

There’s not enough time left so I look for the simplest method to start doing some real refactoring. I don’t really like currentCategory, there’s a lot of duplicated code, and a ton of ifs.

Using subclass to test in often considered an anti-pattern for various reasons one been that with it you test the internal of a class instead of shifting to a higher level of abstraction but in this context is permitted because we just want to preserve the functionality while changing the code and we don’t care if we have to get rid of the test later on.

Building the tests

After having exposed CurrentCategory as a public method we can stub also the places array in order to have fine control over which place a given player is in (in our case player 0). In our case this gives us some advantages like not having roll the dice to move the player arround, just set it’s position do the desired value:

I wrote four simple parametrised tests, one for each category, and the test’s parameter is the place of which I want to check it’s category. As you can see the tests assert that there are 12 positions and that positions 3, 7 and 11 are Rock category: this is an assumption based on what I’ve learned inspecting the code.

Ok, now that the method is covered I’m free to try different things. First of all I substituted the ifs with a much simpler switch statement, but the conditionals are still there. The tests pass. Then I replaced the switch with an array of strings and promoted it to become a private field of the Game class. The tests still pass. With one more step I convert the array of strings in an array of enum because I don’t like magic numbers; The method still have to return a string because if i change the return I’ll have to make changes in a lot of different places in the code. Again, the tests still pass.

End of the iteration

I ran out of time after this refactoring, but there is no doubt that my understanding of the code has increased a lot and that the little method I chose to refactor is a lot easier to understand now that there are no conditionals.

Like this:

In the last post we talked about Mock Objects and what are the difference between them and Spies. We have almost completed our journey through the all the different types of Test Doubles, in this post we are going to introduce the last one: the Fake Object.

There are sometimes where the need of isolation comes from the fact that your tests are running too slow because you are accessing services that need to read or write to the disk or make a network call. In this cases, the best way to improve the test is to use a Test Double that only mimics the same functionality as the service you are currently using. Of course, you need a way to swap the objects during the test, but the techniques to be sure that you can inject your Test Doubles are going to be discussed in a future post.

Let’s make an example

Let’s pretend that you are developing a method that prepares different kind of SMS messages and then sends them using a service that returns an id for the message so you can query it back and check the processing status of the message. The service also stores all sent messages in a queue for later use and the queue has to be manually emptied.

Maybe we can configure the service to avoid sending the SMS message while we are in test, but we still have to wait for the whole round trip to happen, causing a sensible delay in getting the results from the test, and if we have to run lot’s of tests those delays will start to add up. After a while, you end up with tests that take you minutes to run and you stop running them often.

Uncle Bob always talks about how he and his team developed FitNesse without needing a database. But how do they tested the functionalities that dealt with persistent data? well, they isolated the persistence layer and they faked it with an in-memory representation of it.

This is what Fake Objects are for: you swap slow external dependencies of your SUT with the Fake Object and you use them in your test as if they were real.

Can It Be THAT Simple?

Well, it depends. The problem is that Fake Object must have the same functionality as the real one, at least all the functionality the SUT uses, but implemented in a simpler way; for example, our fake SMS service could be implemented like this:

Internally the fake service retains a dictionary of key-value pairs where it saves all the messages that the method Send receives. Even though it’s pretty simple, this implementation is powerful because we can trust that the SUT will believe that it’s using the SmsService that makes the HTTP calls and all that, but in fact, all the operations stay in the memory of the running process, so it’s waaay faster.

Could you give an example of a Fake Object recently used?

In one recent project we used Effort to isolate us from the database.

We were using Entity Framework code first to create the database and then access it, and we discovered this Effort that was an Entity Framework Provider: it implemented the same interfaces and functionality of EF but it did it in an in-memory database so we didn’t have to worry about cleaning the DB in the TearDown phase of our test, we simply destroyed it and created it again, and it was super-fast.

What to do next?

Find a simple functionality on the code you are maintaining that uses an external service and start implementing a fake object based on that functionality; then use it in a test suite to cover your method. If the service is huge and with lots of functionality, don’t get overwhelmed, start small, just a simple implementation that helps you test the method you decided to cover.

Like this:

By using Test Spies we can capture all the indirect outputs of our software to check that it is working correctly. Often times, making the assertions for all the outputs in the testing function leads to lot’s of duplicated code that after a while starts to hinder the purpose of the tests. Sometimes, we would like to do our assertions in the context of the running code and not in the context of the test suite.

Think for example that one of the indirect outputs of your SUT is a disposable object. How you verify that it is in the correct state when it get’s injected to your dependency if it gets destroyed as soon as the method you are testing exits?

Let’s try to understand this problem with an example: let’s say we want to verify that the method CreateAndConfigureDisposable passes the correct object to DependencyObject:

this test looks correct, we configure the SUT, we pass in the TestSpy, we exercise the method we want to test and the we do the assertions. The problem is that as soon as we exit the using block inside LoadStreamAndPosition the disposable object gets, well, disposed and trying to access its state will cause an ObjectDisposedException.

The best way to test this code is to do the assertions in the context of the running code that we want to test. This is where Mock Objects come into play: you put all the assertions inside the Test Double’s method that receives the indirect output.

With this new Test Double the assertions run inside the using block while the DisposableObject still exists. By introducing the Mock Object the test logic flow changes quite a bit, the assertion step is missing and is substituted by a step for configuring the Test Double.

So… what’s the big difference then between Spy Objects and Mock Objects

With a Mock Object you mock an object and with a Spy you spy on it 😉

Just kidding, I read a similar explanation while researching this topic.

The real explanation is that spies are used to collect information about the behavior of the code and then do all the assertions in the testing context while mocks may collect some information (like how many times a method gets called) but all the assertion are done in the context of the running code.

This distinction is important for a few reasons of which this are the two most important in my opinion:Some indirect outputs may not exists outside of the SUT context;

Some indirect outputs may not exists outside of the SUT context;

The code you are trying to test may swallow the exceptions generated by the assertions;

The first one is a case when you are forced to use a mock object because you need to do the assertions while the code is still running; we have already discussed this problem so let’s check the second one.

In this case, we instantiate a non-disposable object that will live after the method LoadStreamAndPosition exists; We still could use a Mock Object if it wasn’t for the Pokémon Exception Handling that is going to catch the exceptions generated by the testing framework hiding all the failing assertions and making us think that the test run correctly.

Like this:

By using Dummy Objects and Test Stubs, we are able to control the inputs of the System Under Test to exercise every part of it during our tests. But of course, not every method that we want to test is going to have one just output or is going to change only the internals of the class that is under test. Most methods have side effects and are going to call other libraries or methods of other objects and we want to be sure that those method calls happen the right amount of times and with the correct parameters.

Let’s suppose we have a method that prepares an invoice when someone check’s out at a hotel. That method is part of a Registration class that takes in a Room and a Guest object and the BookingInformation with all the information about the booking period, like check-in and check-out dates number of people etc.

Then, when the method checkout gets called, it prepares a dictionary of strings and passes it to a library that prints the invoice. This dictionary an indirect output of our method and we want to check if it’s properly set, while also avoiding calling the real method that sends the file to the printer.

We notice that the a printer object is passed in the constructor of the class and that it implements the interface IPrinter. That means we could pass a special implementation of that interface and log the calls and the inputs passed to its methods.

In particular we want to capture the dictionary that is passed to the print method and expose it as a public field to do the assertions. We could also check that we are calling the method just once, or that we are not calling it for when an error occurs.

As you can see, in this test we pass to the Registration constructor the Room, the Guest and the BookingInformation objects properly configured and then we pass also a our Test Double that will get called and will record it’s inputs. After the method CheckOut gets called we have complete access to the information that it prepares and then passes over to the Print method. The SUT (System Under Test) doesn’t know that it’s talking to a test double so if the test passes we are sure that the method will work correctly in production when it will pass the dictionary to the object that will in fact print the invoice.

It’s not always that easy!

Sure, if you are working with some legacy code, chances are that your class doesn’t have the dependency that receives the indirect output nicely injected in the constructor. You could have something like this:

How could you test the indirect output now?

Depending on the code base and how confident you are in refactoring it you could try different strategies like extracting the ugly part of your code to a protected method and then extend the class with a special that you use class just for testing. Another way to address this problem is to isolate your code wrapping the external dependency in a class that you can override like this:

Like this:

In our last post we explored how to use Dummy Objects in order to test our code when we are dealing with objects that are difficult to create. One important restriction on the usage of this kind of test double is that we have to avoid touching the dummy object during our tests. We can easily check that LoadInvoicesByDate throws when from is higher that threshold:

But what happens if we have to pass the first ‘if’ and check that the text of WarningMessage is updated when count equals zero?

In this case the variable count is said to be an indirect input of the code we want to test and in order to control it’s value we need to instantiate a special version of dbFactory that we have under our control. Of course we don’t want to use the real instance of DbFactory because who knows the state of the database… we could never get a count that equals 0. So in our test we are going to need a Test Double called, you guessed it, Test Stub.

The Test Stub will provide you with the indirect input you need no matter what how it gets called. Let’s explain with a test that checks that the WarningMessage field is set when dbFactory.CountInvoices returns zero:

What’s happening here?

First I create a new class that implements IDbFactory and set the return value of CountInvoices to zero, which is exactly the return value we want to have. With this test double we are forcing our code through a path that could have been difficult to simulate with the real implementation.

Moreover, we can generalize a bit our dummy class and set the wanted return values in the tests

Like this:

Let’s pretend we want to add a method to a class. We, of course, are going implement the method using TDD but we have a problem, to create an instance of the class we need to pass in a super-difficult-to-build object. We are sure that our implementation won’t touch this object in any way, like if it smelled funny, but the class needs an’instance of that object. What can we do?

All the horrible code needed to instantiate a working instance of dbFacade is going to obscure the real purpose of the test and make the tests fragile because if something in the procedure of constructing the object changes, a lot of tests are going to fail.

But, do we really need a working instance of DbFacade? we said earlier that we are not going to use it in any way in our new method, so for what we know we could completely avoid it in our tests and just pass a null to the constructor of InvoiceFormatter .

If the constructor of InvoiceFormatter doen’t check for nulls this is a perfectly acceptable strategy and the great thing is that it cleans up the test function. Of course, if we are dealing with a constructor that doens’t accept passing nulls, we have to try to find a different solution.

One solution can be to check if we can instantiate a DbFactory in a simpler way, say with the default constructor and without setting any properties. This won’t result in a working instance of the class but it will be enought for our tests.

Another use of a dummy object is when we are covering a method already implemented and we only need to provide the values for the path that we want to test. For example the method LoadInvoicesByDate receives an IDbFactory

If we are going to test that a DateOverThresholdException is thrown when from is higher than threshold we are free to pass a null as an argument for dbFactory.

To summarize, Dummies are used to put the code that you are going to test in a testable condition whenever you don’t need to read any information form them or call their functions. For that you have stubs, spies, mocks and fakes…

Like this:

One common objection that I get while explaining TDD to my colleagues is that they deal with objects that are too complex to be tested in an automated suite. They either have methods that are too complex (too many interactions with other libraries or classes) or objects too difficult to instantiate (constructors that call to databases or that need to set up a huge graph of dependent objects).

Sometimes the objection is that the program uses some method that reaches to a database or an external service to read (or worse to persist) some information. This normally happens when the developer is working with some legacy code that doesn’t have any real separation between what is the business logic of the software product and what are the external resources that it uses (databases, web services, etc).

Of course, writing automated tests to verify code that calls to a database to save some information can be painful for several reasons:

Databases are slow: the test would run slow and you will not be willing to run them often;

After every test you have to clean the database: this is important because tests should be atomic a reproducible, if the database contains old data, the tests could produce false results. Of course this result in even slower tests;

Your software may be using a database (or service) shared between different applications or different developers: if you are working with a shared database your tests may not be reproducible, you cannot clean the records because you could be deleting other people data. Sharing a database between developers makes your code untestable without some sort of separation from it;

To be able to test your code you have to be isolated from the parts that are difficult to test. By using other objects with the same interface as the one that we want to avoid using.

We have all seen videos of the crash test done on cars to certify their safety. Obviously it wouldn’t be acceptable to do the crash tests with real humans (luckily the time when living humans were used to test katanas is long gone) so they use a dummy that is loaded with sensors to measure the effects that the crash would have on real people.

The software counterpart of these dummies are called Test Doubles and are used in the same fashion: during the tests they are put in those places where it wouldn’t be acceptable or easy to use real production objects. We use Test Doubles to put the software in the condition that we want to test.

The method Contains uses an instance of the class NetworkHandler to load a list of strings from somewhere; this class is defined like this:

public class NetworkHandler
{
public virtual List<string> GetAsList(string uri)
{
// some code that connects to the uri passed as parameter
// and then parses the result and returns a List of strings
}
}

Using the real NetworkHandler there’s no easy way to test that our method returns false when a WebException gets thrown by the method GetAsList. The best way to test this behaviour is to replace in our tests the instance of NetworkHandler with a test double which only purpose is to throw a WebException when the method GetAsList gets called.

Types of Test Doubles

The Test Doubles are divided into different categories depending on their usage in the testing suite. Returning to our dummy analogy, a mannequin is a different Double than a fully featured Crash Dummy, both have the resemblance of a human but they are used in totally different scenarios. In the software world we have:

Like this:

Remember when in the first post of the series I said that we should write the requirements as tests before writing the code that implements it? but it’s important?

As you may have noticed, during the implementation of the requirements in the last post I always wrote part of the requirement before writing the implementation to make it pass, and then refactored the code a little bit by trying to generalize the algorithm and make it clearer to the reader. I was able to change the code and improve it because I Knew there was no way I could break something because the tests would warn me otherwise. Then, after I was satisfied with the refactoring I started again with another piece of requirement.

To put it in programming terms I was more or less following this algorithm:

TDD stands for Test Driven Development and was first introduced by Kent Beck in his game changing book Extreme Programming Explained. This technique is similar to Test First in the sense that you translate in tests your requirements before writing any implementation for them. By following this methodology you guide the development and the design (to some TDD means Test Driven Design) of your program with the help of the feedback that you get from the tests.

Like any methodologies it has some rules you have to adhere in order to be able to say that you actually practice TDD. These are Three Rules of TDD (follow the link for a very good explanation of the rules) :

Never write implementation without tests that prove that it’s correct;

Write the minimum amount of test that makes the test suite fail;

Write the simplest implementation to make the test pass;

By following this rules you enter in a short feedback loop in which you are always sure of the behavior of the program you are writing. You can either have all you implementation working or just one failing test and, as Bob Martin’s article says, almost never run the debugger.

Red-Green-Refactor

This feedback loop is commonly described as the Red GreenRefractor loop because you write a test that have no implementation and which obviously fails (Red), then you write just the smallest implementation to make it pass (Green) and then, when you know the program is working, you start to Refactor and start all over again.

At every refactoring step you take you can run your test and verify that your application is still working the way it was before starting the refactoring phase. And if suddenly you get an error, you know it was introduced by your last change because you never made too many changes without testing them. This means you are just a few seconds away from the last change you did and you remember exactly what you did and why, and in the worst case you can just undo the change loosing just a few seconds of work, instead of hours.

Advantages

When you work following the red green refactor loop you find yourself constantly concentrated in implementing the next requirement, the next, and the next again. It’s easier to enter in a state of Flow when you could continue writing code without interruption. Personally I find it addicting, when I program following TDD I need to use the pomodoro technique to remind me to take a break every 25 minutes or so.

The flow state is facilitated by the fact that, as I said before, you rarely launch the debugger. Instead, you keep checking all your code after every change you make.

Another great advantage is that by following TDD you end up with a pretty easy to understand and easy to verify documentation of your code. Think about the last time you had to maintain a piece of code: you probably had to go through a bunch of methods trying to understand. If you working in TDD has the nice side effect of leaving a trail of tests that exercise your implementation in every possible way so, if you need to understand how a method works you just need to look up the tests that verify that method.

Last but not least is that by having all your code tested, you are protected form introducing bugs in working software. Picture this, how many times have you changed a piece of functionality and found out later on, most probably when your code is already in production, that you broke some other feature of your program? This wouldn’t happen if all your code was covered by a comprehensive suite of tests, because you would discover the regression right after you launch your tests.

So to summarize the main advantages of using this methodology are:

You stay more concentrated on your work;

You almost stop using the debugger;

Tests become a living documentation that help you understand other people code;

High test coverage means regression free changes;

What other advantages do YOU know or think TDD can have? what common objections do you have or have encountered while talking about it with your peers? let us know in the comments and well cover them in a future post.

All this is great but…

If you are thinking that you can’t start using TDD because you work with complex objects or classes you should read the next article of the series when we will cover what Test Doubles are so stay tuned

Daniele Pozzobon

Daniele has more that ten years in the software development industry building solutions to automate processes, helping his clients manage legacy code and teaching them how to become more agile by working from the ground up.

He likes spend his free time with his wife and two kids and when they go to sleep improving his skills by learning new languages and methodologies.

Like this:

In this post we build a practical example using TDD. If you are interested in playing a little bit with the project or you what to complete the requirement as we suggest at the end of the post the files can be downloaded here.

In the previous post on TDD we introduced some of the advantages of having an automated test suite, let’s recap some of them before going a little deeper into some more practical concepts:

First, the computer tells you when you complete your implementation; it can be the most complex pice of requirement, but you don’t have to remember it or try to execute the code in your head to verify if it’s OK, you just run the tests and if it’s green you completed the implementation;

You end up with a set of regression tests that warn you when you introduce a bug while implementing some other requirement. As soon as you run the tests, they verify all the implementation even the one you wrote hundreds of iterations ago;

You gain a lot of time by not having to run tests manually, actually, you stop spending a lot of time in debug mode;

But how do we get all this magic? well, let’s have a look at the implementation of the requirement that you saw in the previous post:

All Approved documents can be read by all registered users which are in the Readers group of higher

Documents which are in the Draft state can be read by Editors, Administrators or by delegated users

Draft documents can be deleted only by Administrators whom cannot Approve them, the only users able to approve the documents are the Editors excluding the Author of the document

This is an actual requirement I got from a client a while ago, it is simple enough to be implemented in a blog post, but it has enough edge cases and can be risky to implement without properly testing the implementation. When we received the requirement, we implemented it in a TDD fashion and after the implementation was finished we did some manual tests. The result was impressive, we couldn’t find any bugs in our implementation and, while the automated test run in seconds, we spent half a day to test all the requirements manually.

In this post I’ll focus only on the implementation of the method that checks whether one user can read a document or not (the first two bullet points) and I’ll leave to you the last requirement of the feature.

Let’s get started

First let me introduce the domain objects:

The rules state some specification on how every User can access a list of Documents. The User class is defined as following:

As you can notice, the document can also be in a defined approval state:

public enum Status
{
Draft,
Approved,
Removed,
Pending
}

On with the implementation

First Step

After defining the domain objects needed to implement the requirements we can start with the implementation by writing the first test. We know that a user that is assigned to the Reader role can read a document in the approved state so, let’s write this as a Test:

First I create a Document and set its ApprovalState to Status.Approved

Then I create a User and assign it to the Editor Role

Then I create a new Instance of the class AuthorizationChecker

Then I call the method CanUserReadDocument passing the user and the document created earlier

Later I check if the result is true or not

This code obviously doesn’t compile because the class AuthorizationChecker and it’s method CanUserReadDocument don’t exists; so I proceed to create them. But what should be the return of the method? Well, because I don’t have any other tests than the one I just wrote I’ll make it return the only value that will make the test pass so I can move on with the tests.

Second Step

What the heck is this you say? well, this isn’t me being stupid, I know there have to be some complex algorithm to compute the result of the function, but for now I have just translated one little part of the requirement and writing a check like