The Rain and The Shade

September 4, 2011

What to inject and what not to inject is the question..

Filed under: Unit Testing — ovaisakhter @ 6:51 pm

Some days back I was having a chat with a friend of mine regarding unit test and DI, we were going though his code and we started discussion on some of the service locators in his services code which I thought should also have been injected(DI or IoC), but he disagreed as he thought these locators are generic enough so they do not need to be injected or wrapped or abstracted. In the similar lines one my team members created a static configuration class in the core and was using it to access the configuration for the application, which started the discussion on how far your should go when it comes to dependency injection.

To answer this question I tried to look into an extreme example in my code and how it paid off in the end.

Recently in a project I wrote some services which were saving certain statistics about a website. An Asp.Net MVC application was calling my application controller service to store the  statistics. These statistics are saved in the context of a Date. In this scenario I can easily use a DateTime.UtcNow.Date inside my service for the Date and be done with it. The challenge comes when you have to write unit tests for this situation. We need to generate some sample data to test the system properly. Considering this situation I created an interface to inject the Date.

public interface IClock
    {
        DateTime Get();
    }

In my unit test project I created an implementation of this such that I can set the Date externally.

Now I created a method in my unit test project

internal class DateProvider : IClock
    {
        public DateTime CurrentDate;

        public DateProvider()
        {
        }

        public DateTime Get()
        {
            return CurrentDate;
        }
    }

I wrote a some code to generate random statistics and recorded the data created in the memory so that I can test it later on. Here is how the code looks like

           var daysToGoBack = random.Next(400, 1000);

           var dateTimeProvider = new DateProvider();
           var externallyControlledActionNotifier = new ExternallyControlledActionNotifier();
           var memorybasedStatisticsLogger = new MemorybasedStatisticsLogger(new IPBasedServerIdentityProvider(),
                                                                             new SiteStatisticsRepository(),
                                                                             externallyControlledActionNotifier, dateTimeProvider);

           for (var i = 0; i < 1000; i++)
           {
               dateTimeProvider.CurrentDate = DateTime.UtcNow.Date.Subtract(TimeSpan.FromDays(random.Next(0, daysToGoBack)));

               memorybasedStatisticsLogger.LogSiteView(surveyConfiguration.RowKey);
               testStatistics.Add(new Statistics { Day = dateTimeProvider.CurrentDate, PageViewed = true })
;

 

so now I am able to generate a random date in the past and I am able  to record in memory the data created so that I can test that correct data was created by my services or not.

As you can see that in this situation injecting a trivial thing like date has saved the day in terms of unit testing. So I believe that you should to inject every possible dependency as a convention, it may come handy at some time….

Advertisements

Leave a Comment »

No comments yet.

RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Create a free website or blog at WordPress.com.

%d bloggers like this: