.NET and me Coding dreams since 1998!

13Feb/080

Design for testability – Dependency Injection Frameworks (Part 4)

I've been away a while (mostly due to vacation time), but I am back and switching gears from NET foundations to TDD subjects. Although I have prepared material for another "How-To Rhino mock" post I would first like to extend my blog post series on how to build software in a way which enables effective TDD.

Therefore, today's post will continue the Design For Testability (DFT) blog posts in which I already babbled about how to design for testability by effectively utilizing the dependency injection pattern on a simple starting example containing mixed DAL code, business code and cross-cutting concerns code:

My next couple of posts in DFT series will cover the same example from the perspective of using a dependency injection framework (which is based on the service locator design pattern):

  • Part 4 - Design for testability - Dependency Injection (DI) frameworks  (this post)
  • Part 5 - Design for testability - Castle Windsor dependency injection framework
  • Part 6 - Design for testability - StructureMap (v2.0) dependency injection framework
  • Part 7 - Design for testability - ObjectBuilder (v1) dependency injection framework

Also, I plan to cover upcoming revisions of DI frameworks as soon they are available somewhere for download (they are unavailable today)

  • Part 8 - Design for testability - Structure Map (2.5) - once it is available for review
  • Part 9 - Design for testability - Unity Dependency Injection Container   - once it is available for review

Setting the stage

At the end of the exploration of the dependency injection based solution (part 3), we ended up with a solution based on Registry design pattern in which we have a DALRepository static class exposing the singleton instance of CompanyManager class which has an internal property UserManager implementing a poor man's dependency injection of the UserManager instance. UserManager also has a UserProvider internal property which  (by default) gets injected with an instance of UserProvider. Something like this:

image

Testability design criteria was achieved by using the InternalsVisibleTo attribute and exposing the internal property setters to unit fixture assemblies so the test methods could easily inject mocked instances of the UserManager/UserProvider to decouple the test from unwanted dependencies. The test therefore can look like this:

 

        
	[Test]
        public void GetActiveUsers_TestCaseOfZeroUsers()
        {
            IUserManager userManager = 
		mockRepository.DynamicMock<IUserManager>();
            Expect.Call(userManager.NumberOfUsersActiveInLast10Days(null))
                .IgnoreArguments()
                .Return(0);
            mockRepository.ReplayAll();

            DALRepository.CompanyManager.UserManager = userManager;
            IList<int> results = DALRepository.CompanyManager.GetActiveUsers();
            Assert.IsTrue(results.Count == 0);
        }

As we can see in line 12, to set the CompanyManager to use UserManager mock, all we needed to do is to set the UserManager property to the appropriate value.

What's wrong with this?

Well, nothing is especially wrong with this code because we have code open for testing, but encapsulated to the developer using the code. In most cases I consider this an acceptable solution - it is not too complete, and does not rely on any supporting code.

But, in the real world, one class often has multiple dependencies even if it doesn't violate the SoC (Separation of Concerns). To support that with our code, we would have to implement multiple internal properties for the class, implement the lazy load, handle threading issues, etc. That would lead to a lot of code noise which we then have to hide in regions. The same story then repeats in other components, which multiplying the amount of code noise.

Another potential problem is that, to support the poor man's injection, we would have to reference the assembly containing the type. This could lead to the increasing risk of cyclical references (especially if the interfaces are located in a separate assembly).

From OOP purist perspective, setting attributes of "production" assemblies just to support testing needs feels "smelly". Adding a new test assembly would require adding a new attribute to the tested assembly.

Summarized: IMHO, while there are not a a lot of problems with the dependency injection pattern, dependency injection frameworks are a simple solution to these problems.

One thing all DI frameworks have in common

They are all based on the service locator pattern, which replaces the direct dependencies between the types with a dependency to well-known-object which, in turn, is capable of finding and instantiating the appropriate types. The following two diagrams show the essence of this pattern:

image

With tight coupling, class A has to refer directly to an instance of Service A.

With the Service Locator pattern, Class A is asking the Service Locator to "find" Service A "from somewhere" and return an instance to Class A.

Some configuration, a little bit of magic and registration

As we can guess from previous picture, the service locator has to have some way of knowing where to find Service A and Service B. Alternatively, the service location can provide a way for Service A and Service B to register themselves. Usually DI frameworks provide 3 ways for this: a configuration file, attribute decoration or manual registration.

XML configuration files

You can use an XML file to define the dictionary of service contracts and service implementations.

Something like this:

<configuration>
	<configSections>
		<section name="DIFrameworkSection" 
			type="DIFramework.SectionHandler, DIFramework" />
	</configSections>

	<DIFrameworkSection>
		<mappings>
			<mapping key="serviceA.Mapping" 
				type="Component.ServiceA, Component" />
			<mapping key="serviceB.Mapping" 
				interface="Component.IServiceA, Component"  
				type="Component.ServiceA, Component" />
		</mappings>
	</DIFrameworkSection>
</configuration>

As we can see in this example, we are adding a new configuration section into the configuration file. This section defines a list of "mappings" which the service locator uses to instantiate the appropriate service.

Usually, DI  frameworks offer two ways of defining mappings:

    • Mapping Definition 1: key - type definition  (ServiceA)

      where the type contains the name of class and the assembly containing the implementation of that class.

A sample call to the service locator in this case would look like this:

ServiceA service=ServiceLocator.GetInstance<ServiceA>();

    • Mapping Definition 2: key - interface - type definition (ServiceB)

      where we add an interface mapping so the service locator can be called with just the interface information provided. This decouples the service locator from a concrete implementation of the class.

A sample call to the service locator in this case would look like this:

IServiceB service=
	ServiceLocator.GetInstance<IServiceB>("serviceB.Mapping");

Attribute magic

Besides the configuration files, DI frameworks usually offer another way of enabling the service locator to automatically discover the services it should instantiate.

The concept is very simple: all the services are marked with an attribute and the DI framework performs reflexive inspection of the types in the given assemblies and registers these mappings. This happens once per application life cycle, during the DI framework's initialization sequence. No configuration files are needed.

Here's an example of what service locator attribute definition looks like (in pseudo code)

[MappingClassAttribute("serviceA.mapping")]
public class ServiceA
{
    ...
}


[MappingAbstractionAttribute("serviceB.abstraction.mapping")]
public class IServiceB
{
    ...
}


[MappingClassAttribute("serviceB.mapping")]
public class ServiceB: IServiceB
{
    ...
}

As we can see from the example above, we have once again defined the mapping to include a concrete implementation of both ServiceA and ServiceB and an abstract interface for IServiceB.

During the init sequence, there's a call to something like this

ServiceLocator.ScanAssemblies();

This causes the Service Locator to recursively walk through the project assemblies and collect of all the concrete and abstract entities marked with appropriate attributes.

The usage is exactly the same as in case of configuration file:

ServiceA serviceA=ServiceLocator.GetInstance<ServiceA>();

IServiceB serviceB=ServiceLocator.GetInstance<IServiceB>("serviceB.mapping");

Manual registration

During the creation of unit test methods, we usually need to swap a "real" service with the mocked instance containing the values needed for unit test execution. We can do this by having two different configuration files: production and test one. Alternatively, we could just have a production configuration file which includes overrides for test methods that require services.

The DI frameworks factory class exposing static method which can be used to define new service locator mappings (or override existing ones).

        
	[Test]
        public void ServiceA_TestXYZ()
        {
            IServiceA serviceA = mockRepository.DynamicMock<IServiceA>();
            
            /* setup values of mocked service
             * ....*/

            ServiceLocator.RegisterService<IServiceA>(serviceA);
            mockRepository.ReplayAll();

            /* perform unit test */
        }

Notice that, in line 9, we have set up the ServiceLocator to return a mocked instance of the type implementing IService which the tested code would then use inside of the test. This looks similar to the dependency injection solution at the beginning of this post, which is not surprising as we have just replaced a custom implementation of dependency injection design pattern with a pre-built dependency injection framework.

What's next?

After this general introduction to DI frameworks concepts, in next part of this Design for Testability series I will give a "How To" overview of Castle Windsor DI Framework (continuing with the same example I have used thus far). I will also highlight the advantages and disadvantages of Windsor compared to other DI frameworks and show some sample unit tests using Windsor.

So, stay tuned :)

[edited by cbeauvais]

Filed under: Uncategorized No Comments
2Dec/071

Designing for testability – an valid architecture choice? (Part 3)

This is third and final part of design for testability series of posts. 
First part of the series covered initial separation of concerns between manager in provider classes, so in case you haven't read that already, jump here and  read it first. 
Second part of the series was focused on decoupling the manager and provider class by separating them with usage of service stub pattern with user provider interface. In case you haven't seen it, check it out here

Redesign step 3 - IUserManager

In part 2 we applied service stub decoupling between user manager and provider by putting internal provider interface between them. In this step, we would in general do the same thing, just this time putting the interface.

As you can probably guess already, we have again the same problem: UserManager is static class with static NumberOfUsersActiveInLast10Days method so we have to remove them if we want to introduce interface usage. But, the difference is in the fact that we could do whatever we wanted with provider class because it was internal, encapsulated class. This time we have a console code using the static manager method so by removing static attributes we would change that code on a significant way  by forcing console to create an instance to access the instance method which could cause some performance issues etc

Today post would show two approaches to solution of that problem:

Both examples would have  common start:

  • removal of the static attributes from UserManager class and NumberOfUsersActiveInLast10Days method
  • extracting an interface IUserManager and implementing it on UserManager

image

Singleton based refactoring

Singleton is very simple pattern, which is based on the idea that if we replace instance constructors with  static factory method we would get the result of instance class behaving like static class.

    public class UserManager : IUserManager
    {
        private UserManager(){/*prevents instance contruction*/}

        public static readonly IUserManager Instance = new UserManager();

In line 3, default constructor is hidden to prevent creating of another instance of UserManager

In line 5,  static field is been defined and set to an instance of Usermanager(). Because of the fact this is static field, this instantiation would happen only once.

Due to the fact that now NumberOfUsersActiveInLast10Days  is an instance method, the way of how it would be invocated in CompanyManager would have to change too, to reflect the new singleton nature of the class.

using System.Collections.Generic;

namespace DAL
{
    public class CompanyManager
    {
        private static IUserManager _userManager = UserManager.Instance;

        internal static IUserManager Manager
        {
            set { _userManager=value; }
        }


        public static IList<int> GetActiveUsers()
        {
            IList<int> result = new List<int>();
            result.Add(_userManager.NumberOfUsersActiveInLast10Days("A"));
            result.Add(_userManager.NumberOfUsersActiveInLast10Days("B"));
            result.Add(_userManager.NumberOfUsersActiveInLast10Days("C"));
            return result;
        }
   

The changes done in CompanyManager are very similar to the one done in UserManager in previous post and in short they are based on replacement of the UserManager direct usage (in lines 27) with a field declared in line 10 and instantiated to point to newly created Singleton Instance property of the UserManager.

Line 11 provide just a way already seen of how to make an option for changing the real UserManager with something implementing the IUserManager during the run time to allow easy testability and all thanks to dependency injection - setter type

With this code in place, testing of the CompanyManager would be very easy and looked something like this

        [Test]
        public void GetActiveUsers_TestCaseOfZeroUsers2()
        {
            IUserManager userManager = mockRepository.DynamicMock<IUserManager>();
            Expect.Call(userManager.NumberOfUsersActiveInLast10Days(null))
                .IgnoreArguments()
                .Return(0);
            mockRepository.ReplayAll();

            CompanyManager.Manager = userManager;
            IList<int> results = CompanyManager.GetActiveUsers();
            Assert.IsTrue(results.Count == 0);
        }

As we can see on this test, we now just mock the direct dependencies - UserManager behavior without going into the internal details on how manager is implemented. "UserManager would return this and I don't care here at all how that would be retrieved "

So we got the decoupled and testable design without exposing the internals of how something is been used.

What is wrong with this code?

Now when we cleaned internal relationships between user manager and user provider and decoupled the external relationship UserManager has, the only thing left is the fact that UserManager.NumberOfUsersActiveInLast10Days method still has mixed crosscutting concerns (validation and caching) with business logic which breaks separation of concerns and decreases testability. A lot of people I know would say that this is not a big deal for them, so for them redesigning for testability could stop here because with singleton pattern implementation there is not much what it can be done further on efficient way.

Registry based refactoring

As I stated earlier, there is another type of solution applicable to this problem and in it we won't make any changes on the UserManager. UserManager class would just lost its static attributes and become and normal instance class. Desired static functionality in this approach will be achieved with a new repository class which would expose unique instances of manager classes through static properties.

Something like this:

namespace DAL
{
    public static class DALRepository
    {
        public static readonly IUserManager UserManager =
            new UserManager();

        public static readonly CompanyManager CompanyManager =
            new CompanyManager();

    }
}

As it can be seen from lines 5 and 8, the normal instances are created and stored in a static repository class which is then used as registry of assembly functionality, removing the need of doing any kind of "being static" targeted development. CompanyManager is just another instance class in this example implementing dependecy injection/service stub design we already saw in this post:

using System.Collections.Generic;

namespace DAL
{
    public class CompanyManager
    {
        private IUserManager _userManager = new UserManager();

        internal IUserManager UserManager
        {
            set { _userManager=value; }
        }


        public IList<int> GetActiveUsers()
        {
            IList<int> result = new List<int>();
            result.Add(_userManager.NumberOfUsersActiveInLast10Days("A"));
            result.Add(_userManager.NumberOfUsersActiveInLast10Days("B"));
            result.Add(_userManager.NumberOfUsersActiveInLast10Days("C"));
            return result;
        }
    }
}

Notice that in Line 7, field is been assigned pointer to new instance of UserManager and that neither class nor method are not static any more. Registry class takes on itself all the burden of adding static attributes.

Testing CompanyManager would in case of repository pattern based solution look like this

        [Test]
        public void GetActiveUsers_TestCaseOfZeroUsers2()
        {
            IUserManager userManager = mockRepository.DynamicMock<IUserManager>();
            Expect.Call(userManager.NumberOfUsersActiveInLast10Days(null))
                .IgnoreArguments()
                .Return(0);
            mockRepository.ReplayAll();

            DALRepository.CompanyManager.UserManager = userManager;
            IList<int> results = DALRepository.CompanyManager.GetActiveUsers();
            Assert.IsTrue(results.Count == 0);
        }

We would create a mocked object of UserManager which would return zero number of users in lines 4-7

In line 10 , we use the DALRepository class CompanyManager static property to set UserManager which would be used by company manager to the mocked one

In line 11, we use the DALRepository class CompanyManager static property to call the GetActiveUsers() method

An additional benefit of Registry pattern based solution

You've probably aware that one of the new cool things Enterprise Library 3.1 can offer is Policy Injection Application block which is a very cool way of removing the cross cutting concern type of code from your business logic. The problem I face usually with PIAB block is that I have to enforce anywhere in the application developers to use PoliciyInjection creation factory method instead of the default constructors objects are offering. Repository pattern used on the way just explained, is IMHO a perfect way of how to encapsulate that policy injection creation code.

We cold rewrite very easy DALRepository class to look like this

using Microsoft.Practices.EnterpriseLibrary.PolicyInjection;

namespace DAL
{
    public static class DALRepository
    {
        public static readonly IUserManager UserManager =
            PolicyInjection.Create<UserManager, IUserManager>();

        public static readonly CompanyManager CompanyManager =
            PolicyInjection.Create<CompanyManager>();
    }
}

The code anywhere would still use the DALRepository,UserManager anywhere in the code without being aware of policy injection occurring in background

I won't go here too deep into the PIAB implementation (I had a session about it already, so in case you care check it out here ) but we can use it easily to perform final redesign of the initial code and remove the validation and caching from business logic.

I would explain here in short how interface based PIAB approach solving this would look.

We would just need to:

  1. decorate IUserManager with next two attributes (lines 5 and 6):
using Microsoft.Practices.EnterpriseLibrary.PolicyInjection.CallHandlers;

namespace DAL
{
    public interface IUserManager
    {
        [CachingCallHandler]
        [ValidationCallHandler]
        int NumberOfUsersActiveInLast10Days(string userName);
    }
}

2. Define appropriate matching rules and active policies in EntLib configuration file

3. Remove the code implementing validation and cahcing

The result will be that method where we have started UserManager.NumberOfUsersActiveInLast10Days would contain only business logic so the it's coherence and maintainability would be highest possible

        public int NumberOfUsersActiveInLast10Days(string userName)
        {
            
            IList<User> userCollection = _userProvider.GetUserCollection(userName);
            int result = 0;
            foreach (User user in userCollection)
            {
                if (user.LastActivity > DateTime.Now.AddDays(-10))
                {
                    result++;
                }
            }
            return result;
        } 

What is wrong with this code?

As far I can tell, there is nothing wrong with this code any more.

Conclusion

We redesigned starting example for testability and that give us clear separation of concerns, loosely coupled component interactions,high maintainability etc.

I do agree that with usage of TypeMocks we could test the original method too, but then we would loose all the side benefits designing for testability brings. Maybe the whole fuzz is because of the wrong terminology: "design for testability" should be called "design for maintainability"  from the reasons this couple of blog posts I hope showed :)

Source code presented in this examples can be found here

Filed under: Uncategorized 1 Comment
2Dec/070

Designing for testability – an valid architecture choice? (Part 2)

This is second part of design for testability series of posts.  First part of the series covered initial separation of concerns between manager and provider classes, so in case you haven't read that already, jump here and read it first, because the story here starts where it ended there. 

Redesign step 2 - IUserProvider

The redesign covered in this bog post would be based on  service stub design pattern. I have already blogged about that pattern so here I would just summarize it as a pattern where direct interaction between two types becomes indirect communication of one class with interface of the second class which decouples second class concrete implementation from communication.

If we would take a look at line 21 of the UserManger class code from last code sample of previous post we would see this line

userCollection = UserProvider.GetUserCollection(userName);

we could see that UserManager is tightly coupled to a UserProvider class and due to the fact that UserProvider talks to DB that prevents easy testing of the UserManager business logic,  because making of any test has a requisite of performing DB related setup.

Provider changes

To get rid of that DB constraint, we would need to define an IUserProvider interface which would have members of the UserProvider class and which UserManager would reference in line 17.

But, right at the start there is a problem:  our provider class is currently static internal class and interfaces are not applicable on any static type members, so to define user provider interface we first had to remove static modifiers from class and method definition.
At the end,  result is provider class implementing provider interface:

 image[46]

UserManager changes

In UserManager class, we would define a static field of the IUserProvider type which would be by default initialized to an UserProvider instance and which NumberOfUsersActiveInLast10Days method would then use that field to call the provider method instead of UserProvider class

We would expose an internal setter property which would set the value of the _userProvider instance field.

Manager code would look then like this

using System;
using System.Collections.Generic;

namespace DAL
{
    public static class UserManager
    {
        private static readonly IDictionary <string , IList<user>> _userCache 
            = new Dictionary<string , IList<user>>();
        private static IUserProvider _userProvider=new UserProvider();

        internal static IUserProvider UserProvider
        {
            set { _userProvider = value; }
        }

        public static int NumberOfUsersActiveInLast10Days(string userName)
        {
            if (string.IsNullOrEmpty(userName))
                throw new ArgumentException("User id not sent");

            IList userCollection;
            if (_userCache.ContainsKey(userName))
                userCollection = _userCache[userName];
            else
            {
                userCollection = _userProvider.GetUserCollection(userName);
            }

            int result = 0;
            foreach (User user in userCollection)
            {
                if (user.LastActivity > DateTime.Now.AddDays(-10))
                {
                    result++;
                }
            }
            return result;
        }
    }
}

In line 8, I there is field of type IUserProvider containing the UserProvider instance

In line 12-15, there is internal setter only UserProvider property which can be used to replace the DB dependable  UserProvider with some mocked/stubbed type implementing the IUserProvider.
All what is needed to be done is to set the UserManager.UserProvider=something and the user manager would use that instead of UserProvider class functionality.

In line 27, UserManager is now using the IUserProvider field value instead of the UserProvider class, decoupling by that manager and provider classes .

Deciding to have internal UserProvider property is solving the request of not exposing internals to the code using class but at the same time it is preventing also test fixture class to use it too :(

Exposing internal members in right amount

Luckily, NET 2.0 offers very easy workaround for this problem and all what is needed is adding of an simple assembly attribute which would declare internal members of the DAL assembly visible to the assembly containing the tests.

We need to open AssemblyInfo.cs  file

image

Presuming our test assembly would be DAL.Test.dll we need to add next assembly attribute definition:

   1: [assembly: InternalsVisibleTo("DAL.Test.dll")]

The result of that setting applied, would be that UserProvider property would be accessible in the Test assembly but not visible to any other assembly. That's how testing the business logic of UserManager.NumberOfActiveUsersInLast10  method could be performed without any DB related set ups because we would just set up UserProvider internal property of the UserManager class to some desired stubbed and mocked provider class

Doing that, we designed for testability (enabled stub/mock  provider injection) and avoid exposing exposing internals to "outer space"

What's wrong with this code?

Let's imagine that there is also CompanyManager class with method GetActiveUsers which calls the UserManager.NumberOfActiveUsersInLast10 days for users which name starts with A, B and C and returns the list of their results. CompanyManager class could look in that case like this

using System.Collections.Generic;

namespace DAL
{
    public class CompanyManager
    {
        private IUserManager _userManager = new UserManager();

        internal IUserManager UserManager
        {
            set { _userManager=value; }
        }


        public IList GetActiveUsers()
        {
            IList result = new List();
            result.Add(_userManager.NumberOfUsersActiveInLast10Days("A"));
            result.Add(_userManager.NumberOfUsersActiveInLast10Days("B"));
            result.Add(_userManager.NumberOfUsersActiveInLast10Days("C"));
            return result;
        }
    }
}

With current code design,if CompanyManager and UserManager would be in the same DAl.Test.dll we could try to use the fact that internals of user manager would be accessible so the test could look something like this

        [Test]
        public void GetActiveUsers_TestCaseOfZeroUsers()
        {
            IUserProvider userProvider= mockRepository.DynamicMock<IUserProvider>();
            Expect.Call(userProvider.GetUserCollection(null))
                .IgnoreArguments()
                .Return(new List<User>());

            mockRepository.ReplayAll();

            UserManager.UserProvider = userProvider;
            IList<int> results= CompanyManager.GetActiveUsers();
            Assert.IsTrue(results.Count==0);
        }

In line 4, we are (courtesy of RhinoMocks) creating a dummy user provider based on IUserProvider interface.

In line 5-7, we are mocking the desired behavior of the user provider - to return empty collection of users (more about mocking: here and  here )

In line 8, we are setting the UserProvider to the mocked provider.

So, as we can see it is possible to mock user manager  dependency and solve the problem but IMHO it is unacceptable solution because to test the company manager business logic we are forced to know and rely on internal concepts of user manager. Beside the fact that this doesn't look cool in our example, in real world there are  usually more then one dependency, so to test the CompanyManager we would have to know and set up internals of a lot of external components, which would make effective writing tests in real world mission impossible.

(to be continued)

Filed under: Uncategorized No Comments
1Dec/072

Designing for testability – an valid architecture choice? (Part 1)

A back while ago, a whole bunch of people I respect : Ayende, Roy Osherove,Udi Dahan and Eli Lopian, started a debate regarding is designing for testability an overkill or a good practice.
(In case you really care about TDD, I'm sue you would enjoy reading some of this posts:Stop designing for testability, TypeMock is Freedom, Test Driven Design vs. YAGNI, Design and Testability - YAGNI, Design vs. Process, Tools vs. Design, Dependency Injection - Keep your privates to yourself, Testable Designs - Round 2: Tooling, Design Smells and Bad Analogies, The Production Value of Seams, Design & Testability – Sense & Sensibility)

Eli is author of the TypeMock mocking framework  which is based on profiler API and that enables TypeMock to mock anything without the need of designing the code on the way we usually  seen in TDD books and articles (design based on Service locator and dependency injection interface style of programing).
The downside of that "design for testability" is that components are exposing their internals which they wouldn't need to do if there won't be testing (constructor accepting interfaces etc).
Eli's point is that we shouldn't design for testability when we have the tools capable to mock dependencies without any required special design.

To me, Eli's point shakes the fundaments of the TDD philosophy, so I spent last couple of days thinking about it and came up with a conclusion that "design for testability" is still an valid architecture choice for me because:

  • TDD design enforces separation of concerns, which increases maintainability, reusability and coherence.
  • TDD design is loosely coupled design which allows easier development and evolution of the system (change is something certain for every system, application, framework... )
  • TDD design enforce test first which helps better understanding of functional requirements, easier project management by enabling realistic progress data

So there are a lot of upsides but what about downsides Eli points to? This series of blog post would try to present a way how to handle them on easy and efficient way. I would start with a code not designed for testability and redesign it in a series of steps without exposing internals or changing the usage of the methods. I hope by that I would prove that it is possible and easy to designing for testability without negative side effects..

Warning: This would be a couple of long blog post with a lot of code examples explaining ratios behind each one of the different phases in (re)design for testability. I'll try to make them as short as possible, but scrolling posts could look scary :)

Use case

Today's use case would be based on a transaction script type of static DAL class which I'm sure we all seen quite some time

For the sake of simplicity our manager class  would have only one method which would load users from aspnetdb database which name starts with a given string  properties and return the number of that users which were active in last 10 days

image

image

That method would be used from a console application which would print out the number of the active users to end user:

namespace Console
{
    internal class Program
    {
        private static void Main(string[] args)
        {
            int activeUserCount=UserManager.NumberOfUsersActiveInLast10Days("M");
            System.Console.WriteLine(activeUserCount);
        }
    }
}

The task of today exercise is to redesign code so it would be designed for testability without exposing internals or complicating  ways of its usage

Initial state

Let's imagine that UserManager class would initially look like this

using System;
using System.Collections.Generic;
using System.Data.SqlClient;

namespace DAL
{
    public static class UserManager
    {
        private static readonly IDictionary<string, IList<User>> _userCache 
            = new Dictionary<string, IList<User>>();

        public static int NumberOfUsersActiveInLast10Days(string userName)
        {
            if (string.IsNullOrEmpty(userName))
                throw new ArgumentException("User id not sent");

            IList<User> userCollection;
            if (_userCache.ContainsKey(userName))
                userCollection = _userCache[userName];
            else
            {
                using (SqlConnection sqlConnection = new SqlConnection(
                    @"Server=.SQLEXPRESS;Database=aspnetdb;Trusted_Connection=yes;"))
                {
                    sqlConnection.Open();
                    const string query = 
                        @"Select * from User where UserName like '%@UserName%'";
                    using (SqlCommand sqlCommand 
                        = new SqlCommand(query, sqlConnection))
                    {
                        sqlCommand.Parameters.AddWithValue("@UserName", userName);
                        using (SqlDataReader sqlDataReader 
                            = sqlCommand.ExecuteReader())
                        {
                            if (!sqlDataReader.HasRows)
                                return 0;
                            userCollection = new List<User>();
                            while (sqlDataReader.HasRows)
                            {
                                userCollection.Add(
                                    new User(
                                        sqlDataReader["UserId"].ToString(),
                                        sqlDataReader["UserName"].ToString(),
                                        Convert.ToDateTime(
                                            sqlDataReader["LastActivityDate"]))
                                    );
                            }
                        }
                    }
                }
            }

            int result = 0;
            foreach (User user in userCollection)
            {
                if (user.LastActivity > DateTime.Now.AddDays(-10))
                {
                    result++;
                }
            }
            return result;
        }
    }
}

As we can see this class does quite lot things. Key points:

In line 14, method is performing argument checking and throwing exception in case of null or empty user name

In line 18, method is checking if there is cached instance of the already retrieved user collection satisfying given criteria

In lines 22 - 51, method contains standard ADO NET type of code code which reads some data from database,pack that data into the collection of User objects

in lines 54 - 62, method is iterating through collection of user objects and for each user active in last 10 days, increments the result which is returned there (this represents business logic)

What is wrong with this code?

This code has very low coherence and it does a lot of different things so if we would look at this initial solution we would see that it contains three major parts:

  1. Cross cutting concerns: argument validation and cache checking
  2. Database access related code
  3. Method "business logic" - counting active users

Mixing of those 3 things in one method  is:

  • decreasing maintainability
  • preventing potential reuse of database code
    for e.g. there could be a need for the same method without caching for a web page calling that method which would use HttpContext based cache. With this design in place we would need to add a bool cacheOn parameter here (and end with spaghetti code) or we would make another method without caching (and end with redundant pieces of code)

Redesign step 1 - UserProvider

The simplest solution would be to follow separation of concerns principle and create a separate internal provider class which would get all the ADO code while "business logic" would stay in manager level

So the new internal static provider class would look like this:

image 

 

using System;
using System.Collections.Generic;
using System.Data.SqlClient;

namespace DAL
{
    internal static class UserProvider
    {
        public static IList<User> GetUserCollection(string userName)
        {
            IList<User> userCollection = new List<User>();

            using (SqlConnection sqlConnection = new SqlConnection(
                @"Server=.SQLEXPRESS;Database=aspnetdb;Trusted_Connection=yes;"))
            {
                sqlConnection.Open();
                const string query 
                    = @"Select * from User where UserName like '@UserName%'";
                using (SqlCommand sqlCommand 
                    = new SqlCommand(query, sqlConnection))
                {
                    sqlCommand.Parameters
                        .AddWithValue("@UserName", userName);
                    using (SqlDataReader sqlDataReader 
                        = sqlCommand.ExecuteReader())
                    {
                        if (sqlDataReader.HasRows)
                        {
                            while (sqlDataReader.HasRows)
                            {
                                userCollection.Add(
                                    new User(
                                        sqlDataReader["UserId"].ToString(),
                                        sqlDataReader["UserName"].ToString(),
                                        Convert.ToDateTime
                                            (sqlDataReader["LastActivityDate"])
                                        )
                                    );
                            }
                        }
                    }
                }
            }
            return userCollection;
        }
    }
}

As we can see, the provider method returns collection of users which name starts with user name. That method can be called by some other method which could have different approach to cross cutting concerns

The manager class would now look like this

using System;
using System.Collections.Generic;

namespace DAL
{
    public static class UserManager
    {
        private static readonly IDictionary<string, IList<User>> 
            _userCache = new Dictionary<string, IList<User>>();

        public static int NumberOfUsersActiveInLast10Days(string userName)
        {
            if (string.IsNullOrEmpty(userName))
                throw new ArgumentException("User id not sent");

            IList<User> userCollection;
            if (_userCache.ContainsKey(userName))
                userCollection = _userCache[userName];
            else
            {
                userCollection = UserProvider.GetUserCollection(userName);
            }

            int result = 0;
            foreach (User user in userCollection)
            {
                if (user.LastActivity > DateTime.Now.AddDays(-10))
                {
                    result++;
                }
            }
            return result;
        }
    }
}

In line 21, UserManager is calling the UserProvider internal class and geting collection of the users which is then processed on the same like in initial implementation

From usage point of how console application is using the code nothing changed in discoverability of the DAL component because intelisense is not showing the provider class (it is internal class)

What is wrong with this code?

If we look at user manager code now, to test that only active users are counted we would need to insert to database one user with active date earlier then 10 days and one with active date older then 10 days so we could check the results. Problem with that is that we test how business logic works (lines 21-27) ; not how database code in UserProvider class works. That's why we have to further redesign the code so we could remove this obstacle.

(To be continued)

 

Filed under: Uncategorized 2 Comments
21Oct/079

TDD – Rhino Mocks – Part 2 – Some common scenarios

 

In first part of the Rhino Mock explorations, I've tried to give answers on what is mocking, what are the different recording modes available in Rhino mocks, how to set up some of results etc.

Today post would continue that by focusing on a few typical mocking tasks. To make this post easier to digest I've wrap those tasks into one "real world" example

Use case

ShoppingCart is class defining the Checkout method which is been called in the moment user wants to make a payment for the purchased items in the cart.
It has two properties: a) UserId - represents the id of the shopping cart user, b) CartAmount - represents the total amount to be charged to user for chosen cart items.

Shopping cart checkout process loads user data using a type implementing IUserRepository. Once user data are loaded, user bank account number is been used by a type implementing the IPaymentProcessor  interface and then if a user has enough funds on his account, cart sends directs payment to payment processor type.

Once the payment would be successfully processed in payment processor, payment processor would raise an event which would signalize the cart that the payment is been completed.  When that would happen cart should store the payment in user payment history and reset the cart value to zero

 

Considering the mentioned use case, we could be testing next things:
1) In case user repository couldn't find an user for a given user id, cart should throw argument exception
2) We need to verify that once payment processor raised an event and signalized that the payment is completed the cart value would be reset to zero and the user repository would add that payment to payment history
3) In case payment attempt would failed due to time out, cart component should recover gracefully and the cart value should stay untouched
4) In case user is having less money on account then the cart value, the payment method should not be called and the cart amount should stay unchanged
5) We need to verify that the performance is optimal by verifying that the retrieving of user data occurred only once

Shopping cart static class diagram

Shopping cart class diagram

As we can see from the class diagram shopping cart uses constructor type of dependency injection design pattern to get pointers to instances of types implementing the IUserRepository and IPaymentProcessor which are then used in checkout method. PaymentSucceed method is a event handler  which handles PaymentSucceed event of the Payment processor.

Although I prefer black box testing approach, we would take a peek at the shopping cart implementation because purpose of this post is not TDD test first methodology, but mocking examples

Checkout method

 

   1: public void Checkout()
   2: {
   3:     User user = _userRepository.GetUser(UserName);
   4:     if (user == null)
   5:         throw new ArgumentException();
   6:  
   7:     double bankBalance = _paymentProcessor.GetBankBalance(user.BankAccount);
   8:     bool userHasEnoughMoney = bankBalance > Amount;
   9:     if (userHasEnoughMoney)
  10:     {
  11:         double oldAmount = Amount;
  12:         try
  13:         {
  14:             _paymentProcessor.MakePayment(user.BankAccount);
  15:         }
  16:         catch (TimeoutException e)
  17:         {
  18:             // logger.Error("Payment time out", e);
  19:             Amount = oldAmount;
  20:         }
  21:     }
  22: }

The method first retrieves the user for a given user name. Then, user bank balance amount is been retrieved  and in case of user having enough money on his account, payment is been made

PaymentSucceed method

   1: void PaymentSucceed(object sender, EventArgs e)
   2: {
   3:     _userRepository.AddToUserPaymentHistory(UserName, Amount);
   4:     Amount = 0;
   5: }

A PaymentSucceed event would be processed by adding user payment history information and resetting cart amount to zero

Test 1. How to define expectations on a method accepting unknown parameters

Rhino Mock concepts: IgnoreArguments()

In case user repository couldn't find an user for a given user id, cart should throw argument exception

Test purpose

Purpose of this test is to verify that if a GetUser would get ANY argument which would cause returning of the null user value, shopping cart checkout method should throw an argument exception

Test code

   1: [Test]
   2: [ExpectedException(typeof(ArgumentException))]
   3: public void Checkout_Verify_That_NotKnownUser_Throws_ArgumentException()
   4: {
   5:     //setting up the stage - retrieval of the user would return null
   6:     Expect.Call(_userRepository.GetUser(null))
   7:         .IgnoreArguments()
   8:         .Return(null);
   9:  
  10:    //stop recording
  11:     _mockRepository.ReplayAll();
  12:  
  13:     ShoppingCart cart = new ShoppingCart(_user.Name, _userRepository, _paymentProcessor, 0);
  14:     cart.Checkout();
  15: }

Test interpretation

In line 6 we define that we expect someone would call  the GetUser method, but because our test is not specific to any constrain related to user name we are passing the null value as the expected userId parameter value but in line 7 we use the IgnoreArguments() method which commands the Rhino Mock framework to disregard what parameters are exactly used as previous method parameters.  In line 8, I've defined that the method would return null value.
Result of lines 6 , 7 and 8 could be read as something like "expect that there would be a call to GetUser method with some unknown parameter for which UserRepository would return null value as result".

Line 11 stops recording mode and line 14 calls the checkout method

Now, if we would take a look at line 3 in Checkout method code snippet we would see that expected call for retrieving user happened and Rhino Mock returned defined null value as result. That null value caused ArgumentException to be thrown in line 5 which is what this test was expecting.

Test 2. How to simulate event raising of mocked object

Rhino Mock concepts: LastCall, IgnoreArguments(), GetEventRaiser(), IEventRaiser

We need to verify that once payment processor raised an event and signalized that the payment is completed the cart value would be reset to zero and the user repository would add that payment to payment history

Test purpose

This test describes:
- how NUnit assert can be used on the non mocked object to verify that mocks made desired effect on it
-  how to simulate event raised on the mock

Test code

   1: [Test]
   2: public void Checkout_Verify_That_Successfull_CheckOut_Would_Make_Cart_Value_Zero()
   3: {
   4:     double cartAmount = 100;
   5:  
   6:     //setting up the stage 
   7:     // 1. Regular user with default data would be retrieved
   8:     Expect.Call(_userRepository.GetUser(_user.Name))
   9:         .Return(_user);
  10:  
  11:     //2. User would have enough money on his account for payment
  12:     Expect.Call(_paymentProcessor.GetBankBalance(_user.BankAccount))
  13:         .Return(cartAmount + 1);
  14:  
  15:     // 3. geting the payment proccessor payment succeed event raiser 
  16:     // which we would use to simulate the async signal that the payment is complete
  17:     _paymentProcessor.PaymentSucceed += null;
  18:     IEventRaiser paymentSucceedEventRaiser = LastCall.IgnoreArguments().GetEventRaiser(); 
  19:  
  20:     // 4. Expect that successfull payment would be stored in user payment history
  21:     _userRepository.AddToUserPaymentHistory(_user.Name, cartAmount);
  22:  
  23:     //stop recording
  24:     _mockRepository.ReplayAll();
  25:  
  26:     ShoppingCart cart = new ShoppingCart(_user.Name, _userRepository, _paymentProcessor, cartAmount);
  27:     cart.Checkout();
  28:     // we now simulate payment suceed event send from payment processor 
  29:     paymentSucceedEventRaiser.Raise(_paymentProcessor,new EventArgs());
  30:     // checking if the cart amount is zero
  31:     Assert.IsTrue(cart.Amount.Equals(0), "Cart amount to be paid not reset to zero.");
  32: }

Test interpretation

This test does next things:

  • in line 8,  we define that the call to GetUser method would return the default user
  • in line 12, we define that user has on his account amount of money greater then the cart amount
  • in line 17, we define expectations that some event handler (null value) would register to the PaymentSucceed event
  • in line 18, we use the LastCall class which is a helper class which points to the last recorded command in the Rhino Mock command stack.
    We can treat that LastCall as "pointer to L17", so the method IgnoreArguments()  can be read as "the null value as subscriber to the PaymentSucceed should be replaced with 'some event handler'".
    Executing GetEventRaiser() method on 'redefined' L17 results with a pointer to PaymentSucceed event which is stored in type implementing the IEventRaiser
  • In line 21, we define expectation that the payed amount would be added to the user payment history
  • in line 24, we stop recording expectations
  • in line 27, we call the checkout method of the shopping cart with valid payment context which should result with completion of the payment
  • In line 29, we use the event pointer retreived in L18 to simulate PaymentSucceed event raising by the PaymentProcessor as the result of successful payment
  • In line 31, we check that the cart value

 

Test 3. How to simulate exception throwing of mocked object

Rhino mock concepts: LastCall, Throw

In case payment attempt would failed due to time out, cart component should recover gracefully and the cart value should stay untouched

Test purpose

This test describes two things:
a) it explains LastCall mechanism for handling void returning methods in Rhino Mocks
b) it explains how to simulate mocked object throwing an exception scenario

Test code

   1: [Test]
   2: public void Checkout_Verify_That_In_Case_Of_Payment_Timeout_Cart_Value_Would_Stay_Unchanged()
   3: {
   4:     double cartAmount = 100;
   5:  
   6:     //setting up the stage 
   7:     
   8:     // 1. Regular user would be retrieved
   9:     Expect.Call(_userRepository.GetUser(_user.Name))
  10:         .Return(_user);
  11:  
  12:     //2. Account check would return information that user is having enough money
  13:     Expect.Call(_paymentProcessor.GetBankBalance(_user.BankAccount))
  14:         .Return(cartAmount + 1);
  15:  
  16:     _paymentProcessor.MakePayment(_user.BankAccount);
  17:     LastCall.Throw(new TimeoutException("Pament failed. Please try later again."));
  18:  
  19:     //stop recording
  20:     _mockRepository.ReplayAll();
  21:  
  22:     // cart amount is less then user account balance
  23:     ShoppingCart cart = new ShoppingCart(_user.Name, _userRepository, _paymentProcessor, cartAmount);
  24:     try
  25:     {
  26:         cart.Checkout();
  27:         Assert.IsTrue(cart.Amount == cartAmount, "Cart amount is changed altought there was timeout roolback scenario");
  28:     }
  29:     catch (TimeoutException)
  30:     {
  31:         Assert.Fail("Checkout procedure didn't recover gracefully from timeout exception");
  32:     }

Test interpretation

This test does next things:

  • in line 9  we define that the call to GetUser method would return the default user
  • in line 13, we define that user has on his account amount of money greater then the cart amount
  • in line 16, we define expectations that the MakePayment method of the mocked payment processor would be called with a user bank account.
    We are not using Expect.Call(_paymentProcessor.MakePayment(_user.BankAccount)) because that is not applicable to the methods returning void value due to the limitations of the C#
  • in line 17, we go around the C# limitation related to void methods and use the LastCall class which is a helper class which points to the last recorded command in the Rhino Mock command stack.
    So the result of LastCall would be pointer to L16
  • in line 17, once we would have a pointer defined with LastCall we use a Throw method to get "MakePayment method execution in L16 would throw an TimeoutException"
  • in line 20, we stop recording expectations
  • In line 26, we trigger the checkout method execution (which would receive TimeoutException defined in L17
  • In line 27 we verify that the cart value stayed unchanged after the TimeoutException occured
  • In line 29, we catch the TimeOutExcpetion and make assertation failing because if that woudl happen that would mean that the cart checkout method didn't recover gracefully from exception so the exception bubbled up outside of the checkout method

Test 4. How to verify that some method of the mocked object was never called

Rhino mock concepts: Repeat.Never

In case payment attempt would failed due to time out, cart component should recover gracefully and the cart value should stay untouched

Test purpose

This test describes:

-usage of Repeat.Never() for testing that some method WAS NOT executed in certain scenario

Test code

   1: [Test]
   2: public void Checkout_Verify_That_User_Without_Enough_Money_Cant_Complete_CheckOut()
   3: {
   4:     double cartAmount = 100; 
   5:  
   6:     //setting up the stage 
   7:     // 1. Regular user would be retrieved
   8:     Expect.Call(_userRepository.GetUser(_user.Name))
   9:         .Return(_user); 
  10:  
  11:     //2. Account check would return information that user is having enough money
  12:     Expect.Call(_paymentProcessor.GetBankBalance(_user.BankAccount))
  13:         .Return(cartAmount - 1); 
  14:  
  15:     //expectation: MakePayment won't be called because user is not having enough money on account
  16:     _paymentProcessor.MakePayment(null);
  17:     LastCall.IgnoreArguments()              /* we don't care which user id should be used */
  18:         .Repeat.Never();                    /* We expect zero method execution*/ 
  19:  
  20:     //stop recording
  21:     _mockRepository.ReplayAll(); 
  22:  
  23:     // cart amount is +1 then user account balance
  24:     ShoppingCart cart = new ShoppingCart(_user.Name, _userRepository, _paymentProcessor, cartAmount);
  25:     cart.Checkout();
  26:     Assert.IsTrue(cart.Amount == cartAmount, "Cart value was modified event the payment was not made");
  27: }
  28:  

This test does next things:

  • in line 8 ,  we define that the call to GetUser method would return the default user
  • in line 12, we define that user has on his account amount of money LESSER then the cart amount is (user is not having enough money to pay)
  • in line 16, we define expectations that the MakePayment method of the mocked payment processor would be called with a null value as user bank account.
    The reason why we pass a null value is that this method shouldn't be called at all in this scenario so it is totally irrelevant what user id would be passed
  • in line 17, we use the LastCall class which is a helper class which points to the last recorded command in the Rhino Mock command stack, which is in this case L16
  • in line 18, we define expectation that the method would be called exactly zero time == expectation that the method won't be called.
    If the method which expectation is defined with Repeat.None would be called, the test would fail
  • in line 21, we stop recording expectations
  • in line 25 ,we call the cart checkout method
  • in line 26, we verify that the cart value is not modified in use case of payment not made

Test 5. How to verify that performance are optimal

Rhino mock concepts: Repeat.Once combined with CreateMock mockery method

We need to verify that the performance is optimal by verifying that the retrieving of user data occurred only once

Test purpose

This test describes:

- Repeat.Once - How to test performance related things such as lazy load

Test code

   1: [Test]
   2: public void Checkout_Verify_That_Retreving_Of_User_Data_Occured_Only_Once()
   3: {
   4:     double bankBalance = 100;
   5:     double cartAmount = bankBalance - 1;
   6:  
   7:     //setting up the stage 
   8:     Expect.Call(_userRepository.GetUser(_user.Name))
   9:         .Return(_user)
  10:         .Repeat.Once();
  11:  
  12:     //stop recording
  13:     _mockRepository.ReplayAll();
  14:  
  15:     // cart amount is +1 then user account balance
  16:     ShoppingCart cart = new ShoppingCart(_user.Name, _userRepository, _paymentProcessor, cartAmount);
  17:     cart.Checkout();
  18: }

This test does next things:

  • in line 8 and 9, we define expectation that the user repository would return default user data
  • in line 10, we constrain that expectation with expectation that the method would be called exactly once.
    This simple constrain is a way how to test lazy loads and similar things
  • in line 13, we stop recording expectations
  • in line 17, we call the cart check out method

 

Test 6. How to customize failed expectation messages 

Rhino mock concepts: Message

Test purpose

This test describes:

- Rhino mock Message method purpose

This test would be the only one failing so we could see the error message

Test code

   1: [Test]
   2: public void Checkout_Verify_That_Retreving_Of_User_Data_Occured_Twice()
   3: {
   4:     //seting up the stage 
   5:     Expect.Call(_userRepository.GetUser(_user.Name))
   6:         .Return(_user)
   7:         .Repeat.Twice()
   8:         .Message("Retrieving of the user did not occurred twice");
   9:  
  10:     //stop recording
  11:     _mockRepository.ReplayAll();
  12:  
  13:     // cart amount is +1 then user account balance
  14:     ShoppingCart cart = new ShoppingCart(_user.Name, _userRepository, _paymentProcessor, 0);
  15:     cart.Checkout();
  16: }

This test does next things:

  • in line 5 and 6, we define expectation that the user repository would return default user data
  • in line 7, we constrain that expectation with expectation that the method would be called exactly twice.
    We saw in previous test that expectation won't be met and this expectation failure would cause test failure
  • in line 8, we define what would be the message which would be outputted if the expectation would fail
  • in line 11, we stop recording
  • in line 15, we call cart checkout method

This test would fail with message

Rhino.Mocks.Exceptions.ExpectationViolationException: Message: Retrieving of the user did not occurred twice
IUserRepository.GetUser("Nikola"); Expected #2, Actual #1.

Conclusion

I believe this couple of examples of how easy and intuitive rhino mock usage is would encourage all the mock sceptics to try use them and TDD development process

I plan to continue posting about Rhino mocks in upcoming days, providing the real world answers on real world type of questions one may have about Rhino mocks

Source code of today's example can be found: here.

 

 

 

Share this post :

Filed under: Uncategorized 9 Comments
6Aug/070

Feature complete development

In a video cast I was watching today (about new things in VS 2008 Beta 2) I heard an unexpectedly interesting part related to the fact that Microsoft building the Visual Studio 2008 was using Agile methodology: sprints, iterations etc.


Scott Gu was speaking in favor about the experiences Microsoft faced while working on VS2008 comparing with standard waterfall process used in VS2005 development


Soma called that paradigm shift: a shift from "Code Complete" to the "Feature complete", which is really awesome description.


By Code Complete he describes typical waterfall methodology:



  1. developers writes the code and at the end we have code complete ,
  2. testers are testing that code then and at the end we are in test complete phase
  3. then goes test automation phase with the automation test complete

With a feature complete, we have now on place Agile principles where the development phase goes in parallel with strictly defined resulting artifacts and expectations at the end of every small iterations which is been then tested by QA people, while development of another feature starts..


Soma also mentioned an interesting concept of feature based branching model, which is another step away from standard waterfall release oriented branching model 


At the end of "Agile in MS" part of this video Soma spoke about the "Feature Crew", "Feature group" team organization Microsoft used in developing Visual Studio 2008 where for each feature they have 5-10 people consisted of developers, testers and project managers. That team is the smallest organizational unit of people working on one unit of work and they are responsible for the "feature  complete". If a member of feature crew leave the team it is the feature crew responsibility to figure out how to reorganize on micro level to make their "feature complete"


All this changes were causing first 4-6 months an "growing pain", because they had to learn how to work in this small teams but by the time they came to Milestone 3 in Orcas they learn the new way of organization and overall effect of that reorganization was very good and feature teams are now working very well.


 


I was really stunt hearing that the biggest bastion of waterfall methodology felt down and that MS finally realized that it is year 2007 and not 1997 :)


Check the video out at S. Somasegar (Soma) and Scott Guthrie on Orcas Beta 2: What's in it?


 


Filed under: Uncategorized No Comments
2Aug/070

Design patterns in real world use case scenarios – Service stub

The second pattern I would be presenting in my mini series of the patterns in real world is one of the main patterns used in Test Driven Development (TDD).

Service stub - decoupled business logic

To get a very detail explanation of what this pattern stands for check out the blog post of the person who 'first documented' it, Martin Fofler P of EAA: Service stub .

Problem - use case

Let’s imagine we have:

- a SomeManager class which has a LoadSomething method which reads data from sql server and that

- OtherType class which has a method which uses the LoadSomething method to get data on which he would imply some business process

That example coded could look like this:

using System.Collections.Generic;

 

namespace TestProject1

{

    public class SomeManager

    {

        public static ICollection<string> LoadSomething()

        {

            List<string> result = new List<string>();

            // read data from sql server

            // result.Add(...);

            return result;

        }

    }

 

    public class OtherType

    {

        public void PopulateSomething()

        {

            ICollection<string> collection= SomeManager.LoadSomething();

            foreach (string s in collection)

            {

                // do something with s

            }

        }

    }

}

 

The problems in this approach are:

  • to test OtherType.PopulateSomething() method I would have to create data rows in some SQL database which would be then read in SomeManager.LoadSomething() and then processed in PopulateSomething() method (which is to be tested). Imagine now that test dependency chain couple levels deep and you would come to the testing nightmare scenario where tests are very, very complexed and inter dependable.
  • if SomeManager.LoadSomething() is been developed in paralel with OtherType.PopulateSomething() there is a possibility that SomeManager won't be finished on time when OtherType would need it to work on its functionality (e.g. DBAdmin's a re too busy to create tables and rows needed)

Summarized: very hard dependency between the types is very inflexible design approach.

Why service stub?

Service stub in short is a pattern where we instead talking to the full type instance we talk to the interface representation of the type and that is exactlly what we need: to talk with abstracted form of the DB  dependable type. If we refer the interface, ANY type implementing the interface could be used in our code. (Usually, this pattern goes together with some form of Dependency injection and service locator)

Rule of thumb

Use service stub if you have dependencies in your code to the parts of system which execution is expensive or dependable on some external information sources.

Problem solution example

Class diagram of the solution

SolutionDiagram

Diagram explanation

What are we testing? OtherType.PopulateSomething method. Not the SomeManager behavior (for which we would have have separate test).

Testing of PopulateSomething method means “test me the result of iteration for given set of data”

Knowing that, we could rewrite our starting example to extract the interface of the SomeManager type, like this

public interface ISomeManager

{

ICollection<string> LoadSomething();

}

 

And our manager would now just implement that interface on the same way it is implemented in starting example

 

public class SomeManager : ISomeManager

{

public ICollection<string> LoadSomething()

{

              List<string> result = new List<string>();

              // read data from sql server

              // result.Add(...);

              return result;

        }

}

 

Now when we have this done, we would alter the OtherType to contain the private field  of ISomeManager type , something like

 

public class OtherType

    {

        private readonly ISomeManager _someManager;

 

 

    }

 

Having this in place we can change the OtherType PopulateSomething method implementation to use the _someManager field instead of constructing the SomeManager instance, something like this:

        public void PopulateSomething()

        {

            ICollection<string> collection = _someManager.LoadSomething();

            foreach (string s in collection)

            {

                // do something with s

            }

        }

The code would compile , but we don't have any code which would set that interface field value to a new SomeManager instance. To keep things decoupled we have to keep the instantiation of SomeManager type outside of the OtherType and one of the ways to do that is to use Dependency Injection - constructor type pattern, by defining constructor which accepts argument of ISomeManager type, something like this

        public OtherType (ISomeManager someManager)

        {

            _someManager = someManager;

        }

With this on place, we have now code which does:"Inside of OtherType.PopulateSomething method use a instance field of ISomeManager type which value someone outside of the OtherType would set"

Usage

Now with this approach I can make for my test purposes a mock object (in this example I would use static mock but dynamic is possible (and preferable) too) 

 

    internal class MockSomeManager : ISomeManager

    {

        public ICollection<string> LoadSomething()

        {

            List<string> result = new List<string>();

            result.Add("1");

            result.Add("2");

            result.Add("3");

            return result;

        }

    }

 

So my test method would look something like

 

        [TestMethod]

        public void TestMethod1()

        {

            OtherType other=new OtherType(new MockSomeManager());

            other.PopulateSomething();

        }

 

Notice that I have constructed the type which implements the ISomeManager interface and pass it to the constructor of the OtherType to use.

One small gotcha of the service stub pattern

The possible downside of this approach could be the fact that with original implementation in real world OtherType usage (TestMethod1 in this example) I would encapsulate the internals how PopulateSomething works:

        [TestMethod]

        public void TestMethod1()

        {

            OtherType other=new OtherType();

            other.PopulateSomething();

        }

That is a valid point, we do want to get flexibility, but not to loose encapsulation. 

To override this obstacle we would use "Poor man dependency injection" technique which would in our example add a new default constructor

        public OtherManager():this(new SomeManager())

        {

        }

That's how even if the user would use the default (encapsulated) constructor the component would work on the way how it worked in original starting state and we would still have all the flexibility

Complete refactored code source

The from example now looks like:

public class OtherType

{

    private readonly ISomeManager _someManager;

 

    public OtherType(): this(new SomeManager())

    {

    }

 

    public OtherType(ISomeManager someManager)

    {

        _someManager = someManager;

    }

 

    public void PopulateSomething()

    {

        ICollection<string> collection = _someManager.LoadSomething();

        foreach (string s in collection)

        {

            // do something with s

        }

    }

}

Problem solved!

Filed under: Uncategorized No Comments
18Jun/070

ARCast.TV – Test Driven Development Primer with Peter Provost

Take a look at the 5 minute video where Peter Provost, one of the Microsoft agile gurus,  explains what is TDD, why it is wrong to call it TDD, what is the relationship between the architecture and TDD etc


Brilliant!


ARCast.TV - Test Driven Development Primer with Peter Provost


Filed under: Uncategorized No Comments
5Apr/071

The Testable Object Pattern

 


Brad Wilson posted about Testable Object pattern which is a n interesting technique how to approach the fact that MVP Presenter constructor  signature can change during the time and by that broke our tests already written


What he is suggesting is defining the new type which would inherit from presenter type and expose static factory parameter method  and internally it would initialize elements of the the presenter constructor.


Looks cool except of the next things:


a) How we would handle different presenter constructors? (If we define overload Create methods we are breaking compatibility later again)


b) I'm not a big fun of creating *helper* types in test classes which are supposed only to support tests. Our tests should test only the "production" types, not the test types - no matter how primitive wrappers they would be...


I think much cleaner solution of the problem Brad is speaking is instead of defining new test type we should solve the problem in presenter type itself


 


Instead of constructor type of dependency injection we can use setter type and define inside of presenter two properties


IView View {set;}


IService Service {set;}


and then replace the presenter its constructor with static factory method (Presenter.CreateNewPresenter()).


That's how  we could solve the problem of test breaking changes of presenter constructor signature without adding additional types


 


Link to The Testable Object Pattern


 


Filed under: Uncategorized 1 Comment
29Mar/070

Espresso Fueled Agile Development : Why Did I Go Agile? Part Two: TDD

Michael Puleio, one of the people from MS PAT team, we have to thank for Web Client Software Factory has an interesting post how he become TDD believer..


There is a piece of that post:


The test team took an initial look, and found a few environmental and configuration issues.  After ironing these problems out, which took a week, I waited for my testers to start filing bugs. 


And I waited…
…and waited…


Read more about what happened on: Espresso Fueled Agile Development : Why Did I Go Agile? Part Two: TDD


 


 


Filed under: Uncategorized No Comments