The Inquisitive Coder - Davy Brion’s Blog

Thinking outside of the typical .NET box

Archive for the 'Test Driven Development' Category


Introducing TDD: How would you do it?

Posted by Davy Brion on 26th August 2008

In about 2 weeks, our Belgian ALT.NET group will give a somewhat large presentation on what ALT.NET is and some of the important concepts and practices. As a part of that presentation, i’ll give a 10 minute ‘lightning-talk’ about TDD. I’ve already got a bit of an idea as to what i’m going to say, but i figured i should ask my readers for some input.

So, if you had to give a short talk (remember, only 10 minutes) about TDD, targeted to an audience that has little to no experience with it, or may not even know anything about it, what are the things you’d really want to highlight? And what are the things that probably aren’t worth mentioning for such a short talk?

Or for those of you who have little to no experience with, or knowledge about TDD, what are the things you’d like to hear if someone were to introduce the concept to you in about 10 minutes?

Posted in ALT.NET, Test Driven Development | 8 Comments »

Test Doubles: When To (Not) Use Them

Posted by Davy Brion on 13th August 2008

I’m currently introducing somewhat ‘advanced’ testing techniques such as Dependency Injection and using Mocks/Stubs to my team members. They’re getting the hang of it pretty fast, but the typical “do i need to mock this object for this test?” question came up pretty frequently at first, and sometimes it still does. Which is only normal when you’re starting out with these techniques. So i figured it would be useful to list some guidelines about it in a post.

First of all, i’ll use the term test double instead of mock or stub or whatever for the remainder of this post to (hopefully) avoid any confusion. Gerard Meszaros (author of the excellent book xUnit Test Patterns) provides the following definition of a test double:

A Test Double is any object or component that we install in place of the real component for the express purpose of running a test.

One thing that’s not clear from just that sentence (it is very clear in the book, but not when you merely look at this sentence in isolation) is the fact that it usually only makes sense to use a double for what Gerard calls Dependent-On Components (more commonly referred to as dependencies) of the code you are testing.

So, when does it make sense to use a test double, and when are you better off just using the real component? A lot of people think differently about this, but i have found the following guidelines to be the most efficient with regards to keeping the tests focused, fast, easy to set up, and most importantly: meaningful.

If a component uses an external resource (a database, a file, a remote service, …) either directly or indirectly, then i always replace the component with a double when i’m testing code that is dependent on it. An external resource usually means that the component is either slow (keep in mind that you want to run a couple hundred tests per second), hard to set up (required data or files or whatever), or a possible source of unpredictability (tests should never fail and then work again without changing code). Using doubles allows you to avoid the slowness, makes it easier to set up any required state, and they are always predictable.

Components that do not use external resources yet still require a lot of work to set up (for complex in-memory calculations for example) are also good candidates to be replaced with test doubles. Even if the real component is lightning fast, if you need to write a lot of set up code just to get the real component to behave the way you want it to for a specific test, then you’re better off using a double for it. Tests should be focused, so you don’t want a lot of code in them (either in the test method itself or in the setup/teardown methods) if that code doesn’t really pertain to the functionality that you are testing in that fixture. Performing a bunch of set up for dependencies is simply a waste of time while writing it, while maintaining it, and it’s also a distraction while reading it. So, always avoid that, even if the components don’t use external resources.

That’s pretty much all for when you should use doubles. Now, when should you not use doubles? My answer to that is very simple: when there is no clear-cut benefit to it. If you’re using classes that do not have external resources and hardly require any set-up, then by all means, use the real components in your tests. Using test doubles is a great technique, but it is only a means to an end. Using doubles merely for the sake of using doubles will not lead to better tests. It’s very important to keep that in mind.

I often hear developers say something like “but if you’re not using the real components in your tests, how do you know for sure that they work?”. Well, the answer to that is also pretty simple. Each component should have its own dedicated tests. Yes, even components that use the database, or the file system or even remote services or whatever else you can think of. These components will be used at runtime, therefore they need to be tested. Test them as thoroughly as you can, but no more than that. Test them in isolation, perhaps even in a different test suite that you don’t need to run every time. Perhaps you don’t even need to run these tests automatically? But that would be a nice subject for a different post :)

Anyways, the guidelines (or rules of thumb) are just that… they’re only guidelines, not strict rules. As we all know, when it comes to coding, there are always exceptions (no pun intended). If you follow these guidelines and some things still feel like it requires too much work or are causing too many issues, then there’s probably a better solution for that specific problem still waiting to be found. Don’t be afraid to spend a bit of extra time searching for it. It might save you a hell of a lot of time later on.

Posted in Test Driven Development | 4 Comments »

Mocking Dilemma, Solved!

Posted by Davy Brion on 21st July 2008

A coworker of mine, Tom Ceulemans, has provided a very nice solution to the mocking dilemma i posted earlier. I like this solution so much, i think it deserves its own post :)

The original question was basically: how do you do access a protected member in a test? I didn’t want to make it public because it is a base class, and i was hoping to avoid making it protected internal and then exposing the internals to my tests assembly.

Tom’s solution is very nice, and IMO, very clean as well. The trick is to create a derived abstract class from the class you want to test and then write the TestFixture as an inner class of the newly created class.

The test shown in the previous post would now look like this:

    public abstract class MyAbstractClassTestWrapper : MyAbstractClass

    {

        [TestFixture]

        public class MyAbstractClassTests

        {

            [Test]

            public void CallsProtectedAbstractMethod()

            {

                var mocks = new MockRepository();

                var myObject = mocks.DynamicMock<MyAbstractClassTestWrapper>();

 

                myObject.Expect(m => m.DoSomethingSpecific()); // <= no more compile error

                myObject.Replay();

 

                myObject.DoSomethingInteresting();

                myObject.VerifyAllExpectations();

            }

        }

    }

I like it :)

Posted in Test Driven Development | 11 Comments »

Mocking dilemma

Posted by Davy Brion on 20th July 2008

Suppose you have the following abstract class:

    public abstract class MyAbstractClass

    {

        public void DoSomethingInteresting()

        {

            // some stuff would go here…

            DoSomethingSpecific();

            // more stuff would go here…

        }

 

        protected abstract void DoSomethingSpecific();

    }

What do you do if you want to write tests that set expectations on the protected abstract method?

Ideally, i’d be able to do this:

        [Test]

        public void CallsProtectedAbstractMethod()

        {

            var mocks = new MockRepository();

            var myObject = mocks.DynamicMock<MyAbstractClass>();

 

            myObject.Expect(m => m.DoSomethingSpecific()); // <= compile error

 

            myObject.DoSomethingInteresting();

            myObject.VerifyAllExpectations();

        }

But as the comment points out, this causes a compiler error because the DoSomethingSpecific method is inaccessible to anything except derived classes.

So what is the best way to deal with this? For this example, i could manually create a derived class, set a flag in its DoSomethingSpecific implementation and then assert on the value of that flag. But that approach doesn’t really scale well to complexer classes. If i want to use a mocking framework for this, i have two options (that i can think of right now): i either make the abstract method public so the above code would compile, or i can make it protected internal and then allow my internal members to be visible to my Test project.

I dislike both approaches. I wholeheartedly agree with the “Public vs Published” stance, but making a method that really should only be accessible from derived classes public merely for testing purposes just doesn’t sit well at all with me. Changing the abstract method’s visibility from protected to protected internal seems to be the lesser of two evils, although i’ve always seriously disliked the internal keyword and especially extending the visibility of it through the InternalsVisibleTo keyword. This approach just screams “HACK!” to me, but in this case i can’t really think of anything better.

If anyone call tell me what the best way would be to deal with this specific scenario, please do share :)

On a sidenote: i am happy about the fact that i do seem to periodically reflect on the merit of my many ‘rules’ such as “thou shalt not expose thy privates to an even larger group than the internal circle to whom they’ve already been shown”. I’ve already mentioned that i’ve had it with rules that serve only theoretical purposes without any practical merit… there’s no reason why my own rules should be excluded from this :)

Posted in Test Driven Development | 21 Comments »

My Guide To Effective Test Driven Development

Posted by Davy Brion on 14th July 2008

When it comes to Test Driven Development (TDD), there are 4 kinds of developers:

  1. The kind that doesn’t do it, and doesn’t care about it
  2. The kind that doesn’t do it, but is intrigued by it and would like to learn more
  3. The kind that does it, but wonders why it’s not as easy as everyone claims it is
  4. The kind that does it effectively

I don’t spend time on the first category, and i consider myself to be of the last category so this post is targeted at the 2nd and 3rd categories. Hopefully, some of the stuff in this post will help you on your way to using TDD effectively. It’s basically just a list of stuff to keep in mind while doing TDD. So without further ado, i present you with my guidelines to effective TDD:

Keep your tests small and focused

This is probably the thing that most people get wrong, which leads to all kinds of problems. Developing software is all about managing complexity. How can you effectively do that? By trying to keep things simple. No matter how smart or gifted you are, the more complex you make things, the easier it is for you to make mistakes. You do need a high-level picture of how things should work in your application or system, but the actual implementation is something that needs to point itself out while you’re working on it. Always start small and simple. Think of one small feature, write a test for that, and then write the code to make that test work. While you do this, make sure you don’t get sidetracked by other features that suddenly pop into your head. Make a note of them, and when you’re done with the test and the code you were working on, proceed with writing a test for one of the things you thought of earlier. But the key is to keep adding small features (after having written small tests for them of course). Some of you are now thinking “but what if i need to add a big feature?”. Well, then you need to break that ‘big feature’ down into smaller parts.

After a short while, you will have accumulated a bunch of small things that work. Because you implemented them in a focused way, and because you were forced to think about how you’d use those features in your test before actually implementing them, you normally should’ve ended up with a bunch of little parts that are easy to use. And your tests already prove that they work. That means you can start using these parts (they can be classes or just individual methods) to get other things (new features) working. Whenever you use a part that you already finished earlier (including its tests of course, since you wrote them before you wrote the finished code of the part) you don’t need to worry about the correctness of that part in the tests that you’re writing for whatever new feature you’re working on. This is something that a lot of people get wrong. I can not stress this enough: the correctness of dependent code should be covered by its own tests!

I believe the approach outlined above really is the key to effective TDD. Obviously, there are more guidelines, but this is the one that will have the biggest impact on your experiences with TDD.

Use dependency injection

Dependency injection (DI) is a really simple technique that offers more advantages than simply making TDD easier to do. But the focus of this post is on TDD, so i won’t get into the other advantages. You can find an introduction to this technique here.

Keep your tests fast

A slow test is like body oder: the problem is only gonna get worse until it’s taken care of properly. If you have a bunch of smelly people in one room, you really don’t want to be there. It’s the same thing with a bunch of slow tests… nobody wants to be around those. That means that most people won’t run the tests frequently, which is a shame. So you really need to keep those tests fast if you want people to run them often. The best way to achieve this is to mock/stub/fake your dependencies in your tests. If you’ve used DI properly, this is really easy to do. Every dependency that can slow down your test, or make it unreliable because of factors that are external to the test, should be mocked/stubbed/faked. Some of you might be wondering: “but how can we be sure that the code really works when it’s using the real dependency?”. Well, the real dependency should be covered by its own suite of tests that thoroughly tests the behavior of that code. If the correctness of the dependency is properly covered by its own tests, why on earth would you subject yourself to the downsides of using the real dependency in tests that have to cover other parts of code? Using mocks/stubs/fakes allows you to keep your tests focused on that piece of code they actually should cover and it helps in keeping your tests fast. What’s not to like?

Minimize access to the database in your tests

A lot of people use their database in a lot of their tests. This usually leads to slow tests, and excessive test set up to satisfy all relational constraints which in turn leads to fragile tests. None of this is beneficial to your productivity. But of course, you do have to test the code that uses your database. The key is to write tests for each specific database activity (a query or any other kind of statement). Write tests that verify that a query returns the correct values. Write tests that verify that a query does not return incorrect values. Be sure to cover everything you want to cover to make you feel secure about that query. And stop right there… every other part of your code that needs access to this specific query should be talking to an object (a dependency) instead of performing this query itself. Use mocks/stubs/fakes instead of the real dependency in the tests of that other code. By replacing your real data access code with mocks/stubs/fakes in your tests, you can make your tests very fast, and you can usually simplify the set up of the tests as well.

Don’t over specify your tests

If you’re using mocks, be sure not to write tests that are too tightly coupled to the implementation of the code you’re testing. If you frequently have to modify your tests because you changed the implementation of the class without it affecting the observable behavior of the class, then you probably have over specified tests. Mocks can be a very effective tool to increase both your productivity and the quality of your tests, but when used wrong it might lead to a lot of unnecessary extra work. This is quite an extensive topic in its own right, so i can’t do it any justice within the context of this post, but it is something to keep in mind even if you don’t have experience with mocking yet.

Don’t be afraid to throw tests away

If you’re doing some heavy refactoring, you might break a few tests. Depending on how extensive the refactoring is, you might break a lot of tests. A lot of people feel that they have to keep those tests around… but that’s not always the case. Take a close look at the tests… Do they still make sense after the refactoring? Perhaps you need to refactor those tests as well instead of going through hoops to get all of them working again. Sometimes you may need to modify a few tests to get them working again… But sometimes, those tests simply aren’t valid anymore. If they are, throw them out instead of wasting time on them. If the assertions of the tests are still important, but it’s too much work to modify the tests, it may actually be less work to simply rewrite them against the refactored code. There is no one right answer here, but you may need to learn how to look at your tests from more angles then you may currently be used to doing.

Conclusions

This is by no means a definitive list of things that you need to keep in mind while doing TDD… But i do think these guidelines may be the most important ones. If you follow these guidlines, you should end up with fast tests that are easy to understand, not a pain in the ass to maintain, and most importantly: verify the correctness of the code under test.

Once you have that, the code and design of your system is probably pretty flexible and it will be easier to adapt as time goes on. And this is probably the single biggest advantage of doing effective TDD.

It might take you a while to learn how to do all of this effectively. But that’s ok… there’s nothing wrong with that at all. Baby steps are better than no steps at all, right? Just keep in mind that if doing TDD hurts, you’re not doing it right… yet. Figure out where the pain comes from, try to fix the cause and try again. It’s a repetitive process and you wont get it right immediately. None of us did.

Posted in Test Driven Development | 2 Comments »

Mocking expensive template methods

Posted by Davy Brion on 11th July 2008

One approach to implement business logic that i’ve seen a couple of times now, is to use a class that implements an execution pipeline, which triggers virtual methods in a specific order and provides general error handling or transaction management for that pipeline. The idea is usually to get most developers to write their code in a similar manner, while trying to relieve them of the burden of exception handling, transaction management or whatever else you want to provide in the pipeline execution. This approach is far from ideal (personally i think it sucks), but when you’re facing a large application with a bunch of code that already uses this, you pretty much gotta live with it.

Here’s a simplified example of a class implementing such an execution pipeline:

    public abstract class Command

    {

        private readonly List<string> errorMessages = new List<string>();

 

        public void Execute()

        {

            try

            {

                CheckAuthorization();

                CheckErrorMessages();

                ValidateInput();

                CheckErrorMessages();

                ProcessInput();

                CheckErrorMessages();

            }

            catch (Exception e)

            {

                Logger.Log(e);

                // do something clever that developers supposedly don’t think of

                // …

            }

        }

 

        protected virtual void CheckAuthorization() { }

        protected virtual void ValidateInput() { }

        protected virtual void ProcessInput() {}

 

        protected void AddErrorMessage(string errorMessage)

        {

            errorMessages.Add(errorMessage);   

        }

 

        private void CheckErrorMessages()

        {

            if (errorMessages.Count > 0)

            {

                // throw some kind of exception which contains all of the messages

            }

        }

    }

There are many problems with this approach, the most important one being that most developers usually put too much code directly within the virtual methods and usually even using concrete dependencies, which leads to all kinds of testing difficulties. I hope you spotted the outdated exception handling approach, but i’m not even gonna get into that in this post.

Here’s an example of how a small piece of business logic might be implemented with this approach:

    public class DeleteCustomerCommand : Command

    {

        private Customer customer;

        private CustomerDataLayerComponent customerDAL;

 

        public void Execute(Customer customer)

        {

            this.customer = customer;

            customerDAL = new CustomerDataLayerComponent();

            Execute();

        }

 

        protected override void CheckAuthorization()

        {

            if (!AuthorizationManager.IsAllowedToAccess<DeleteCustomerCommand>())

            {

                AddErrorMessage(“sorry buddy, no access”);

            }

        }

 

        protected override void ValidateInput()

        {

            if (customerDAL.GetOutstandingOrderCount(customer.Id) > 0)

            {

                AddErrorMessage(“Customer can’t be deleted when there are outstanding orders”);

            }

        }

 

        protected override void ProcessInput()

        {

            try

            {

                customerDAL.Delete(customer);

            }

            catch (Exception e)

            {

                AddErrorMessage(e.Message);

            }

        }

    }

If you’ve been reading this blog for a while, then i hope you can spot the 2 biggest problems already. The first is this line:

            customerDAL = new CustomerDataLayerComponent();

And the second is this one:

            if (!AuthorizationManager.IsAllowedToAccess<DeleteCustomerCommand>())

These are 2 concrete dependencies which can’t easily be replaced with mock implementations while testing this code. Basically, any code that is performed by the data access layer component, or the AuthorizationManager’s static IsAllowedToAccess method will have to be set up properly in every test that you write for this class. Depending on what needs to be done during that set up, this can really become a major pain in the ass. For instance, if you wanted to write a test that would check if the right error message was created when the user is not allowed to access this command, then you have to make sure that the call to IsAllowedToAccess method actually fails. Depending on the implementation of the AuthorizationManager, this can be quite tedious work. Keep in mind that because of the template method pipeline approach that is used here, you need to set this up for every test for this class. The same thing goes for the call to the GetOutstandingOrderCount method of the data access layer component that is being performed in the ValidateInput method.

Suppose you have the following tests for this class:
AddsErrorMessageWhenUserDoesntHaveAccessToThisCommand
DoesNotAddErrorMessageWhenuserDoesntHaveAccessToThisCommand
AddsErrorMessageWhenCustomerHasOutstandingOrders
DoesNotAddErrorMessageWhenCustomerHasNoOutstandingOrders
DeletesCustomerWhenThereAreNoErrorMessages
DoesNotDeleteCustomerWhenThereAreNoErrorMessages

For each test, the entire pipeline is executed. That means that for each test, you need to set up data that is not always relevant to the test itself. You’re actually doing more setting up than you really need to do for that small piece of code you’re trying to test. You can see where this is going right? These 6 tests would basically lead to unecessary expensive setup.

Now suppose you have an application where you have hundreds of these command classes, and thousands of tests. Running all the tests becomes so slow it’s unbearable, not to mention all the wasted effort that has been spent writing all that unnecessary setup, and maintaining it as well because you can be pretty sure that a lot of tests are pretty fragile.

Now, ideally you’d want to make sure that you could talk to a mocked AuthorizationManager and to a mocked data access layer component when this class is being tested. After all, these are dependencies of this class, and thus, the functionality offered by those dependencies should be covered by their own tests. So to correctly test the functionality of this class, you really don’t need to use the actual implementations. In the tests of this command class, you need to verify that it reacts properly to the possible return values of the dependencies.

Unfortunately, refactoring to the approach i just mentioned is not always feasible. So how do you try to minimize the pain? A coworker of mine actually pointed out an approach that allows us to at least minimize the set up that is needed for some tests, without having to redesign the existing code. His suggestion was to mock template methods in the pipeline that were unrelated to the current test. If you can’t redesign the existing code, this is probably the next best thing.

Let’s give it a shot. Suppose we want to test the CheckAuthorization method. We basically don’t need anything to happen in the other methods when we’re testing the authorization, so we’ll try to mock those with empty implementations:

        [Test]

        public void AddsErrorMessageWhenUserDoesntHaveAccessToThisCommand()

        {

            var mocks = new MockRepository();

            var command = mocks.PartialMock<DeleteCustomerCommand>();

 

            PrepareAuthorizationManagerToDenyAccess();

            command.Stub(c => c.ValidateInput()).Do(new Action(EmptyMethodThatDoesntDoAnyting));

            command.Stub(c => c.ProcessInput()).Do(new Action(EmptyMethodThatDoesntDoAnyting));

            mocks.ReplayAll();

 

            AssertThrows<Exception>(“sorry buddy, no access”, () => command.Execute(new Customer()));

        }

Note that in order for this to work, you have to change the protected virtual methods to internal protected (and use the InternalsVisibleTo attribute if your tests are in a different assembly). For this test, we only had to set up the authorization manager, nothing else.

If you want to test the ValidateInput method, you could do something like this:

        [Test]

        public void AddsErrorMessageWhenCustomerHasOutstandingOrders()

        {

            var mocks = new MockRepository();

            var command = mocks.PartialMock<DeleteCustomerCommand>();

            var customer = new Customer();

 

            CreateOutstandingOrderFor(customer);

            command.Stub(c => c.CheckAuthorization()).Do(new Action(EmptyMethodThatDoesntDoAnyting));

            command.Stub(c => c.ProcessInput()).Do(new Action(EmptyMethodThatDoesntDoAnyting));

            mocks.ReplayAll();

 

            AssertThrows<Exception>(“Customer can’t be deleted when there are outstanding orders”,

                () => command.Execute(customer));

        }

In this test, we only had to set up the order for the customer, but we didn’t have to set up the authorization manager. If you implement your tests this way instead of going through the entire pipeline each time, and thus, taking the performance hit of all the unnecessary set up every time, you can probably cut a lot of time off of those test runs.

Thanks to Joel for giving me the idea :)

Note: again, i want to make it clear that i don’t advocate using the template method pipeline approach. If you absolutely want to use it, at least inject each dependency in a way that allows easy mocking. If you can’t modify existing code that already is implemented like this, the partial mocking technique in this post is a good idea, but ideally, this entire thing should be avoided.

Note: i just spotted the EmptyMethodThatDoesntDoAnyting typo… it’s getting late so i’m not even gonna bother fixing it :P

Posted in Test Driven Development | 2 Comments »

How To Write Testable ASP.NET WebForms

Posted by Davy Brion on 6th July 2008

Microsoft’s upcoming ASP.NET MVC framework makes it easy to write tests for your application layer logic. But what about those of us who are stuck with ASP.NET WebForms? You can still write highly testable ASP.NET WebForms with only a little bit of extra effort. But that extra effort really pays off in the long run. In this post, i’ll give a detailed description of one approach that has worked for me really well. I first started using this approach for a project at work sometime last year. It allowed me to cover my application logic with a lot of tests which weren’t a hassle to write or run, so naturally i’ve always wanted to write a detailed post on this subject. I hope you’ll like it :) (Btw, if you’re new to mocking this might serve as an introduction to that as well)

This is the screen we’re going to create:

The very first thing you’ll notice is that i completely suck at graphic design. So try to ignore the crappy look, and lets focus on what this screen should do. A user can perform a search on products based on the name, the product category and the supplier of the product. After clicking the Search button, the user is presented with a list of products that match the search criteria. Next to each product is an Edit link (because i was too lazy to find a nice image for this). When clicked, the application should navigate to an Edit screen where the chosen product can be edited. To keep this example short (this post will be long enough already!), that’s all for this screen.

So what are the things that we would want to test for a simple screen like this? For starters, i want to be sure that when this page is loaded, it retrieves the list of product categories and suppliers, and that it displays them. Another thing i want to test is that when the search button is clicked, the screen has to retrieve all the matching products and display them. And when the Edit link is clicked, i want to make sure that this screen navigates to the Edit screen with the correct parameters.

I’m going to do this using an MVP (Model-View-Presenter) approach, the Supervising Controller variant to be more specific. As with any pattern, i believe you should use it in a pragmatic way. In this implementation i don’t follow every rule strictly, i will just try to provide an approach that offers you all the advantages of the pattern, while trying to make it as easy as possible to implement.

I’m also going to use a couple of techniques that will allow me to write fast tests which should be easy to maintain as well. I’ll use a mocking framework (Rhino Mocks), Dependency Injection and an Inversion of Control container (Castle Windsor). Don’t worry if you’re unfamiliar with these topics, when needed i’ll try to explain everything. And of course, you’re always welcome to ask questions :)

Anyway, enough talk… let’s get started shall we?

First, we need an abstract way to define a View (which corresponds to a page basically):

    public interface IView

    {

        bool IsPostBack { get; }

        bool IsValid { get; }

 

        void DataBind();

        void DisplayErrorMessage(string message);

    }

Every page in this application implements the IView interface, although each page also implements a more specific interface. Each view will have a controller, which has to be able to communicate with the view. This communication is usually limited to providing data and telling the view to perform a DataBind operation, or telling it to display a certain message. But the controller can sometimes also request information from the view, like asking if the view is currently in a PostBack, or if the view is currently valid, or whatever else you might need.

This is the interface of the page shown above:

    public interface IProductList : IView

    {

        IEnumerable<ProductCategoryDTO> ProductCategories { get; set; }

        IEnumerable<ProductOverviewDTO> Products { get; set; }

        IEnumerable<SupplierDTO> Suppliers { get; set; }

    }

As you can see, this interface merely provides a few properties on top of what the IView interface provides. This is one example of where i deviate from the typical implementations of this pattern. Most people define events in the view’s interface for each user action that can occur. The controller then subscribes to these events when it is bound to the view, and it handles those events. While that is theoretically a nice approach, i found it to be somewhat cumbersome, both in writing more code than you really need and making the tests a bit more cumbersome to write. So in my implementation, the Controller actually offers public methods for each user action. The view then simply calls the controller’s public methods when these actions occur. This means that both the view and the controller know about each other. A lot of purists will not like this, but i believe the (mostly theoretical) downsides to the view and the controller knowing about each other don’t match up to simpler implementation.

Anyways, you probably want to know what the controller looks like. We’ll get to that soon, but first we define a base Controller type that each controller will inherit from:

    public abstract class Controller<T> : Disposable, IController where T : IView

    {

        protected Controller(T view)

        {

            View = view;

        }

 

        protected T View { get; set; }

    }

Right now, this is a pretty simple class, but as you implement more screens, you will most likely refactor common controller methods to this base class. In this application, the controller will usually communicate with a proxy to a remote service. That proxy is actually the model in this implementation. Obviously, if you don’t need a service layer you can simply use the real Model objects in the controller. But since a proxy to a remote service is an expensive object that needs to be cleaned up properly, i made the controller inherit from the Disposable class. Each derived controller will need to provide a method to clean up its expensive resources.

The specific controller for this application looks like this:

    public class ProductListController : Controller<IProductList>

    {

        private IProductManagementService service;

        private readonly IProductsNavigator navigator;

 

        public ProductListController(IProductList view, IProductManagementService service,

            IProductsNavigator navigator) : base(view)

        {

            this.service = service;

            this.navigator = navigator;

        }

 

        protected override void DisposeObjects()

        {

            if (service != null) service.Dispose();

        }

 

        protected override void ClearReferences()

        {

            View = null;

            service = null;

        }

    }

We’ll add the methods to handle the user actions later on, so this class is not complete yet. You can see that the controller has 3 dependencies… the first being the view, the second is the service and the third one is an instance of the IProductsNavigator interface. I use small navigator classes to perform all of my navigation because it makes it easy to test that a navigation has occurred without actually having to move to another page.

The IProductsNavigator interface looks like this:

    public interface IProductsNavigator

    {

        void GoToEdit(int? productId);

        void GoToSearch();

    }

Nothing special here, just a method to move to the edit screen with an optional product Id (the edit screen is also used to edit a new product’s data, and then the productId parameter will be null) and another method to move to the Search screen. The code of the class that implements this interface merely does a redirect to the correct page. But it’s important to get that code out of the controller because it would lower testability.

Anyways, let’s get to the whole writing tests part. Because we’re going to write as much code as possible in the controller instead of the view, we will simply test the controller with a fake view and a fake model (service). That’s right, we’re going to test our application code for this page without an actual page. We will mock the view and the service, and we’ll pass those mocked dependencies to the controller. In our tests we will then instruct the mocks to behave like their real versions, depending on what we’re trying to test.

First of all, we’ll define a base controller test class:

    public abstract class ControllerTest

    {

        protected static void PrepareServiceToReturnResponses(IService service, ServiceRequestResponseSpy spy,

            params Response[] responses)

        {

            spy.SetResponsesToReturn(responses);

            service.Stub(s => s.Process(null))

                .IgnoreArguments()

                .Do(new Func<Request[], Response[]>(spy.GrabRequestsAndReturnGivenResponses));

        }

    }

This class will simply provide some helper methods that will be common to our controller tests. The method that is already there can be ignored for now, but if you want to know what it does you can look here. I’ll also (briefly) explain it when it’s used in a test.

Our test class needs to set up the mocked dependencies and provide a way to create the controller with those mocks so we already have the following code:

        private MockRepository mocks;

        private IProductManagementService service;

        private IProductList view;

        private IProductsNavigator navigator;

        private ProductListController controller;

 

        [SetUp]

        public void SetUp()

        {

            mocks = new MockRepository();

            service = mocks.DynamicMock<IProductManagementService>();

            view = mocks.DynamicMock<IProductList>();

            navigator = mocks.DynamicMock<IProductsNavigator>();

        }

 

        private ProductListController CreateController()

        {

            controller = new ProductListController(view, service, navigator);

            return controller;

        }

Nothing special here… the mocks are create before each test in the SetUp method, and we have helper method which creates the controller with the mocks so we don’t have to do this ourselves in each test.

Ok, now we can finally get to our first test. I don’t know about you, but i really hate it when a page performs code that it really doesn’t have to do in a PostBack. So we’ll guard against that with the following test:

        [Test]

        public void DoesNotRetrieveCategoriesAndSuppliersOnLoadIfPostBack()

        {

            view.Stub(v => v.IsPostBack).Return(true);

 

            mocks.ReplayAll();

            CreateController().Load();

 

            service.AssertWasNotCalled(s => s.Process(null), options => options.IgnoreArguments());

        }

We instruct the mocked view to return true for the IsPostBack property. Then we create the controller, call its Load method and we verify that the Service’s Process method was not called in any way. Pretty simple, right? It does get a bit more complicated when we want to test that the correct data is retrieved when the page is initially loaded:

        [Test]

        public void RetrievesCategoriesAndSuppliersOnLoad()

        {

            var categoriesToReturn = new ProductCategoryDTO[0];

            var suppliersToReturn = new SupplierDTO[0];

 

            var spy = new ServiceRequestResponseSpy();

            PrepareServiceToReturnResponses(service, spy, new GetProductCategoriesResponse(categoriesToReturn),

                new GetSuppliersResponse(suppliersToReturn));

 

            view.Expect(v => v.ProductCategories = categoriesToReturn);

            view.Expect(v => v.Suppliers = suppliersToReturn);

            view.Expect(v => v.DataBind());

 

            mocks.ReplayAll();

            CreateController().Load();

 

            view.VerifyAllExpectations();

            Assert.IsNotNull(spy.GetRequest<GetProductCategoriesRequest>());

            Assert.IsNotNull(spy.GetRequest<GetSuppliersRequest>());

        }

First, we create two empty arrays of objects that we’ll instruct the mocked service to return when its Process method is called. We’re using the PrepareServiceToReturnResponses method here, which you’ve seen listed in the ControllerTest class. It basically allows you to provide Response instances and it uses the ServiceRequestResponseSpy class to hook into the mocked service. If you want to know the details behind this technique, go here.

Then we set some expectations on the view. We expect that its ProductCategories property will be set to the value that we’ve instructed the mocked service to return. Same thing for the Suppliers property. Then we define an expectation that the view’s DataBind method should be called. After that, we create the controller, call the Load method and we verify that all expectations on the view were met. We also assert that the service indeed received the proper requests.

So what code did we just test? Well, the Load method of the controller, which now looks like this:

        public void Load()

        {

            if (!View.IsPostBack)

            {

                var batcher = new ServiceCallBatcher(service);

                batcher.Add(new GetProductCategoriesRequest());

                batcher.Add(new GetSuppliersRequest());

                View.ProductCategories = batcher.Get<GetProductCategoriesResponse>().ProductCategories;

                View.Suppliers = batcher.Get<GetSuppliersResponse>().Suppliers;

                View.DataBind();

            }

        }

The load method uses the service to retrieve the product categories and the suppliers, in one remote call. You can find more information on that here and here.

Now we can write a test to make sure that the controller behaves correctly when the user presses the Search button:

        [Test]

        public void CallsTheServiceToSearchForProductsAndBindsResultsToView()

        {

            const string productPattern = “whatever”;

            const int categoryId = 4;

            const int supplierId = 7;

 

            var productsToReturn = new ProductOverviewDTO[0];

            var spy = new ServiceRequestResponseSpy();

            PrepareServiceToReturnResponses(service, spy, new GetProductOverviewsResponse(productsToReturn));

 

            view.Expect(v => v.Products = productsToReturn);

            view.Expect(v => v.DataBind());

 

            mocks.ReplayAll();

            CreateController().Search(productPattern, categoryId, supplierId);

 

            view.VerifyAllExpectations();

            var request = spy.GetRequest<GetProductOverviewsRequest>();

            Assert.AreEqual(productPattern, request.NamePattern);

            Assert.AreEqual(categoryId, request.CategoryId);

            Assert.AreEqual(supplierId, request.SupplierId);

        }

This should look somewhat familiar by now. We set up an empty array of ProductOverview instances that we want the service to return when it receives a request. We then set the expectations on the view, just like we did in the previous test. Then we create the controller and call its Search method with some search parameters. Then we verify that the view’s expectations were met, and we use the service spy to retrieve the request that it received. We then verify that the request parameters are the same as the ones we sent to the controller.

The Search method of the controller looks like this:

        public void Search(string name, int? productCategoryId, int? supplierId)

        {

            var response = service.GetProductOverviews(

                new GetProductOverviewsRequest(name, productCategoryId, supplierId));

            View.Products = response.Products;

            View.DataBind();

        }

Our final test is very simple. We just need to make sure that the page navigates to another page with correct parameter when the user presses the Edit link next to a product:

        [Test]

        public void NavigatesToEditProductScreenWhenEditProductIsTriggered()

        {

            const int productId = 5;

 

            navigator.Expect(n => n.GoToEdit(productId));

 

            mocks.ReplayAll();

            CreateController().EditProduct(productId);

            navigator.VerifyAllExpectations();

        }

This really doesn’t need any explanation right? :)

And the code in the controller looks like this:

        public void EditProduct(int productId)

        {

            navigator.GoToEdit(productId);  

        }

We’ve already implemented all of the logic we need for this page, and we haven’t even started working on the page yet! First we provide a bit of plumbing code to make sure our pages are capable of correctly creating the correct controller and making sure it gets disposed properly when the page has been rendered. So we have the following base page:

    public abstract class NorthwindPage<T> : Page where T : IController

    {

        protected NorthwindPage()

        {

            Controller = CreateController();

        }

 

        protected T Controller { get; private set; }

 

        protected abstract T CreateController();

 

        protected override void OnPreRenderComplete(EventArgs e)

        {

            base.OnPreRenderComplete(e);

            Controller.Dispose();

        }

 

        // there are also some small helper methods in here that aren’t really

        // relevate to the example so i left them out

    }

And the code of the real page looks like this:

    public partial class ProductList : NorthwindPage<ProductListController>, IProductList

    {

        public IEnumerable<ProductCategoryDTO> ProductCategories { get; set; }

        public IEnumerable<ProductOverviewDTO> Products { get; set; }

        public IEnumerable<SupplierDTO> Suppliers { get; set; }

 

        protected void Page_Load(object sender, EventArgs e)

        {

            Controller.Load();

        }

 

        protected override ProductListController CreateController()

        {

            return Container.Resolve<ProductListController>(new { view = this });

        }

 

        protected void SearchButton_Click(object sender, EventArgs e)

        {

            Controller.Search(NameTextBox.Text, GetSelectedId(ProductCategoryList), GetSelectedId(SupplierList));

        }

 

        protected void EditProductLink_Click(object sender, EventArgs e)

        {

            Controller.EditProduct(GetIdForCurrentRow(sender as IButtonControl));

        }

 

        public override void DataBind()

        {

            if (ProductCategories != null && Suppliers != null)

            {

                var categories = new[] { new ProductCategoryDTO { Id = -1, Name = “All” } }.Union(ProductCategories);

                var suppliers = new[] { new SupplierDTO { Id = -1, CompanyName = “All” } }.Union(Suppliers);

                PrepareDropDownList(ProductCategoryList, categories, “Name”, “Id”);

                PrepareDropDownList(SupplierList, suppliers, “CompanyName”, “Id”);

            }

 

            if (Products != null)

            {

                ProductsGrid.DataSource = Products;

            }

 

            base.DataBind();

        }

    }

Most of this is pretty straightforward, except maybe the code in the CreateController method. I don’t like to repeat myself (although i’m aware that i often do that anyway) so you can find the story behind that line of code here.

So we’ve minimized the code in the actual page, and the important parts are all covered with tests. You’re probably thinking “that is a lot of test code for so little real code”, and you’re right… this approach does lead to a lot of test code. But it also leads to a lot less debugging :)

This was a pretty simple example… but you can of course use this approach on complex screens as well. You just need to provide a public method for each kind of action on your controller, and try to do as much as possible in the controller. You really want the view to remain as “dumb” as possible. It should delegate all logic to the controller, and then simply focus on data binding, and in screens where you can edit data, client-side input validation. The more code you can push to your controller, the more you can cover it with tests.

For instance, for this particular screen you probably want to add sorting capabilities. Just provide a public Sort method on your controller which takes a sort expression and sort direction as parameters. Then you can write tests to verify that the controller indeed offers the view a properly sorted list of data when the Sort method is called. In your view, you would then simply need to call the Sort method and pass the correct parameters when the user clicks on a column header. Or if you want to provide a Delete link (or image, ideally) next to each product, you’d provide a public Delete method on the controller which takes the product’s Id as the parameter. Then you can start writing interesting tests, like verifying that the controller sends a DeleteProductRequest instance to the service, and perhaps retrieves an updated list of products to bind to the view. Or better yet, you can write a test where the mocked service throws a business exception when you try to delete a product, to verify that the controller displays the correct message on the view and doesn’t remove the product from the view’s list.

Anything is pretty much possible, you just gotta make it work :)

Hope you enjoyed this post, i for one am very happy to have finally written it since it’s been on my TODO list for months now :)

kick it on DotNetKicks.com

Posted in ASP.NET, Test Driven Development | 6 Comments »

Testing batched Service calls

Posted by Davy Brion on 29th June 2008

Now that we can batch WCF calls, and do so with readable code we still need a way to test this.

Suppose that we have a page where we need to display a dropdown list of product categories and suppliers. This is the code in the controller of that screen for the Load event:

            if (!View.IsPostBack)

            {

                var batcher = new ServiceCallBatcher(service);

                batcher.Add(“categories”, new GetProductCategoriesRequest());

                batcher.Add(“suppliers”, new GetSuppliersRequest());

                View.ProductCategories = batcher.Get<GetProductCategoriesResponse>(“categories”).ProductCategories;

                View.Suppliers = batcher.Get<GetSuppliersResponse>(“suppliers”).Suppliers;

                View.DataBind();

            }

When i’m testing my controllers, i like to use mocked service instances, and i set expectations on the methods that should be called and the parameters they receive. With my batching technique, i don’t really execute specific methods on the service because the batcher calls this method:

        Response[] Process(params Request[] requests);

My Request classes are really simple, and to keep them simple they don’t override the Equals method. This makes it hard to set expectations because the Request instances are created by the controller, and i can’t set expectations on the Process method using Request instances that would equal the Request instances that were passed to the batcher by the controller. This makes it hard to test that the service is called correctly. If a Request type contains properties (which are really service method parameters) you really want to be able to test that those properties contain the correct values. Also, you want to make sure that the correct Requests are sent to the service. But if they’re handled by this very generic Process method, it makes it hard to verify correct usage during a test.

So how can we properly test the code listed above? I came up with the following approach. First we need a class that we can use to set up the Response instances to return from the service’s Process method, and to capture the Request instances that are passed to the Process method:

    public class ServiceRequestResponseSpy

    {

        private Request[] receivedRequests;

        private Response[] responsesToReturn;

 

        public void SetResponsesToReturn(params Response[] responses)

        {

            responsesToReturn = responses;

        }

 

        public T GetRequest<T>(int index) where T : Request

        {

            return (T)receivedRequests[index];

        }

 

        public Response[] GrabRequestsAndReturnGivenResponses(params Request[] requests)

        {

            receivedRequests = requests;

            return responsesToReturn;

        }

    }

Now we can write our test like this:

        [Test]

        public void RetrievesCategoriesAndSuppliersOnLoadIfNotPostBack()

        {

            view.Stub(v => v.IsPostBack).Return(false);

 

            var categoriesToReturn = new ProductCategoryDTO[0];

            var suppliersToReturn = new SupplierDTO[0];

            var spy = new ServiceRequestResponseSpy();

            spy.SetResponsesToReturn(new GetProductCategoriesResponse(categoriesToReturn),

                new GetSuppliersResponse(suppliersToReturn));

 

            service.Stub(s => s.Process(null))

                .IgnoreArguments()

                .Do(new Func<Request[], Response[]>(spy.GrabRequestsAndReturnGivenResponses));

 

            view.Expect(v => v.ProductCategories = categoriesToReturn);

            view.Expect(v => v.Suppliers = suppliersToReturn);

            view.Expect(v => v.DataBind());

 

            CreateController();

            controller.Load();

 

            view.VerifyAllExpectations();

            Assert.IsNotNull(spy.GetRequest<GetProductCategoriesRequest>(0));

            Assert.IsNotNull(spy.GetRequest<GetSuppliersRequest>(1));