All we need is our code be Testable!

What a coincidence, as the discussion on Uncle Bob’s recent post, “Manual Mocking: Resisting the Invasion of Dots and Parentheses” was heating up on one side, I ended up on a similar argument with one of my collegues regarding if mocking framework is all the times necessary to test our code just because it is available in our reference path. With too many views already came in on this discussion on Uncle Bob’s post, this is my point of view from my poor thoughts.

Either I am using a mocking framework or not,

  • First, my priority is to make sure that “my code should be testable“.
  • Second, I should keep my testing code, be simple (can be stupid) so that it can be quite clearly understood. (Remember KISS!)
  • Third, I would remember ‘YAGNI!‘. If you think you can achieve a good testable code easily with hand-rolling the stubs, then probably ‘You Ain’t Gonna Need’ another mocking framework to do the same.

So when do I need a mocking framework? I prefer mocking framework,

  • When I want to check if my code is interacting with some external API’s as expected (Interaction Test).
  • When I am unable to easily stub out an external API that my code is interaction with, in order to get some data or expected response.

If the external API belongs to my own code base and if there are not many things expected from the external API from my code, the I would prefer hand-rolling the stub rather going with mocking framework even if it cost me to add couple of more lines in the code base. I believe that would keep things simple, readable and also helps me to keep my testing code in one place.

Again I wish to re-emphasize that my ultimate goal is to keep my code,

  • simple,
  • testable and
  • readable.

Apart from the above, I probably wouldn’t care, if my IDE is helping me to quickly generate the expected code or if I end up in a stone age period because I don’t use mocking frameworks. I will use them only when I really need them.

BTW, the following is the hand-rolled test code (in C#) that I finally ended-up with after arguing with my friend regarding the mocking framework should be used or not for this case.  For me it looked quite simple and easily understandable even without a need of a mocking framework which probably wouldn’t have added much value in this case.

using System;
using NUnit.Framework;

namespace Configuration.UnitTests.Client.Caching
{
   [TestFixture]
   public class CacheCleanTimerTest : ConfigurationTestBase
   {
      private const double FiveMinInterval = 5*60*1000;
      private CacheCleanTimerStub cacheCleaner;

      [SetUp]
      public void Setup()
      {
          cacheCleaner = new CacheCleanTimerStub(FiveMinInterval);
      }

      [Test]
      public void ShouldClearCacheWithinGivenClearCacheTimeSpan()
      {
           cacheCleaner.appSetting = "18:00";
           Assert.IsTrue(
           	cacheCleaner.ClearAllCache(
           		GetSignalTime(18, 2)));
      }

      [Test]
      public void ShouldNotClearCacheAfterCacheClearingTime()
      {
          cacheCleaner.appSetting = "18:00";
          Assert.IsFalse(
          	cacheCleaner.ClearAllCache(
          		GetSignalTime(18, 6)));

      }

      [Test]
      public void ShouldNotClearCacheBeforeTheCacheClearingTime()
      {
          cacheCleaner.appSetting = "18:10";
          Assert.IsFalse(
          	cacheCleaner.ClearAllCache(
          		GetSignalTime(18, 6)));
      }

      private DateTime GetSignalTime(int hour, int minute)
      {
          return new DateTime(
          	DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day,
          	hour, minute, 0);
      }
   }

   internal class CacheCleanTimerStub : CacheCleanTimer
   {
      public string appSetting { set; get;}

      public CacheCleanTimerStub(double timerInterval)
      : base(timerInterval)
      {
      }

      public override string CacheClearingTime()
      {
         return appSetting;
      }
   }
}
Advertisements

About this entry