Geeks With Blogs
Mark Pearl

 

So I am new to TDD and have been enjoying the ride of learning a new approach – today I came across an interesting situation that I thought I would blog about. I was writing a class that had all sorts of string manipulation in it. I needed some helper methods that would extend my string manipulation abilities. I had read somewhere that I should avoid static methods when doing TDD so I wrote the initial helper class to look something like this…

    public class StringHelper
    {
        public string ReverseStringEx1(string value)
        {
            char[] charArray = value.ToCharArray();
            Array.Reverse(charArray);
            return new string(charArray);
        }        
    }
 

This just didn’t feel right to me… In my calling code a call would have looked like the following…

    class Program
    {
        static void Main(string[] args)
        {                        
            Console.WriteLine(new StringHelper().ReverseStringEx1("123"));            
            Console.ReadLine();
        }
    }

 

After speaking to some of the fellow developers and asking them why static methods were avoided in TDD, the main motivation was that they are hard to replace / mock out and so prohibit testing methods that use them. In my instance I don’t really think this is a concern. The methods that I was writing were self contained and had no state propagating outside the actual method. SO I refactored my helper class to look like the following…

    public class StringHelper
    {        
        public static string ReverseStringEx2(string value)
        {
            char[] charArray = value.ToCharArray();
            Array.Reverse(charArray);
            return new string(charArray);
        }        
    }

This meant when referencing the helper method in code it would look something like this…

    class Program
    {
        static void Main(string[] args)
        {                                    
            Console.WriteLine(StringHelper.ReverseStringEx2("123"));            
            Console.ReadLine();
        }
    }

That seemed cleaner that what I had been doing before, but then extension methods came to mind and so I did one final refactor which ended up with my helper class looking as follows…

    public static class StringHelperExtensions
    {
        public static string ReverseStringEx3(this string value)
        {
            char[] charArray = value.ToCharArray();
            Array.Reverse(charArray);
            return new string(charArray);
        }
    }

 

Which meant the use of the helper would look something like the following…

    class Program
    {
        static void Main(string[] args)
        {                                                
            Console.WriteLine("123".ReverseStringEx3());
            Console.ReadLine();
        }
    }

 

I think from a readability point of view this is probably the easiest, my concern here is have I done something that is going to bite me in the butt down the road. Right now my mindset is as long as I focus on any helper methods being small and not containing any state then I should be okay. I can exercise the methods in unit tests and I would not see why I would want to mock these types of methods out… any comments  / advice would be much appreciated.

Posted on Wednesday, November 2, 2011 11:27 AM C# | Back to top


Comments on this post: TDD – Static Methods

# re: TDD – Static Methods
Requesting Gravatar...
I agree with your fellows, the static and extension methods are very hard to mock. In your sample it's not necessary to mock the string revert method since its very simple and didn't rely on any other part. But thinking if you have a static (extension) method that communicates with a printer, fax, etc. In this case you have to mock or stab this method but the it would be very difficult.
Left by Shaun on Nov 02, 2011 4:04 PM

# re: TDD – Static Methods
Requesting Gravatar...
To understand the issue with static methods you have to identify your SUT (system under test). For your scenario, your SUT is Program.Main(). That is what you want to test. However, you cannot test that part in isolation because you have a dependency on the static StringHelper. As a result, you cannot mock StringHelper to fulfill your testing of Program.Main().
Left by ptran on Nov 02, 2011 10:35 PM

# re: TDD – Static Methods
Requesting Gravatar...
ptran: I'm pretty new to unit testing, but isn't mocking helper methods a bit extreme? If helper methods are tested first, I would be pretty confident that I can use these methods directly in other classes, without injecting dependencies and mocking those classes. It's not like they are replaceable components, they're just simple, easy to test helper methods.
Left by MetaSam on Nov 03, 2011 3:17 PM

# re: TDD – Static Methods
Requesting Gravatar...
You are correct. Your StringHelper is not hitting an external dependencies. So, there is no need to mock this class.
Left by Ptran on Nov 03, 2011 6:51 PM

# re: TDD – Static Methods
Requesting Gravatar...
you could access the static method via a delegate that is passed in to you SUT
Left by your name on Nov 03, 2011 7:15 PM

# re: TDD – Static Methods
Requesting Gravatar...
Mark, what you need here is to be able to stub out your collaborator (StringHelper). Not to mock it. You want StringHelper.ReverseStringEx() to return a canned value so that you can continue to test your SUT in isolation. So, with this method being static it is hard to override the logic to return a canned value. Roy has an excellent book on making code testable: http://osherove.com/. A must read.
Left by ptran on Nov 03, 2011 10:59 PM

Your comment:
 (will show your gravatar)


Copyright © MarkPearl | Powered by: GeeksWithBlogs.net