Click here to Skip to main content
15,881,852 members
Articles / Programming Languages / C#

Extension Methods and Unit Testing in VS2008

Rate me:
Please Sign up or sign in to vote.
4.17/5 (12 votes)
4 Nov 2007CPOL8 min read 50.1K   132   39   4
Create some useful Extension Methods using .NET 3.5, then test your new methods using the built-in unit testing functionality in VS2008 Professional.

Unit Tests in VS2008

Contents

Introduction

This article is going to be using some of the new features available with the new Visual Studio 2008 Beta 2 Professional edition. Download it now if you haven't already. I have been using it for almost 3 months now, and I have not looked back. I now use it for all my HTML and CSS editing, including writing this very article. Not only does it have a host of new features, but you get performance improvements too, and even though it is still a beta version, I have had absolutely no problems or crashes whilst using it.

Some New VS2008 Pro Features

  • Multi-Targeting - targets different .NET Framework versions.
  • Split View WYSIWYG - view both design and source at the same time.
  • JavaScript intellisense and debugging.
  • Improved CSS support.
  • Nested master pages.
  • Unit Testing.

Some New .NET 3.5 Features

I am not going to explain what some of the new features are, but rather leave it to Scott Guthrie and let his blog posts do the talking.

Extension Methods

One of the features that caught my eye straight away was Extension Methods. Extension methods "allow developers to add new methods to the public contract of an existing CLR type, without having to sub-class it or recompile the original type." They also make other powerful features, like LINQ, possible. I also then realized that it is now possible to "add" functionality to the existing framework classes, for example, the System.String class. I have always had a class of static string utility methods that I use in all my projects and applications. It is a part of a utils class library that I have built and grown over the years while using .NET. So this was the perfect opportunity to rewrite my utilities class library using version 3.5 and take advantage of (and learn) the new features. I have already started doing this, and I am blogging about it as I go.

First Example

An extremely simple (and useless!) example of an Extension Method can be seen in the following code:

C#
namespace Utils.MyExtensions
{
     public static class JunkExtensions
     {
          public static string ToSomethingElse(this string input)
          {
                return input.PadLeft(10);
          }
     }
}

Please note that your Extension Methods must be defined inside a non-generic static class. Now, to use the Extension Method, include the namespace in your code:

C#
using Utils.MyExtensions;

...and your new Extension Method is now available to you, as you can see in the intellisense:

Extension Method in intellisense

When NOT To Use Them

I will be the first to admit that Extension Methods can be both useful and powerful, but when is enough enough? Scott Guthrie says in his post: "As with any extensibility mechanism, I'd really caution about not going overboard creating new extension methods to begin with. Just because you have a shiny new hammer doesn't mean that everything in the world has suddenly become a nail!" You couldn't say it any better than that. Listen to Scott - he knows best. You must not convert all your static utility methods to Extension Methods. What is the point? Do you really want to see a string class that has hundreds of methods available, but you only use 10% of them most of the time? Obviously not.

When To Use Them

You should only convert your most reusable, everyday static methods. Don't just create an Extension Method because you can; create one because you know it will help you code smarter. I create Extension Methods that, I think, improve and extend the framework, and that I feel should also be part of the framework. When I find myself asking the question: "But why didn't they include this method in the framework?", a new Extension Method usually follows shortly after.

Also, make Extension Methods that are just wrappers around your utility methods. This way, the utility code and the Extension Method code can be kept separate, so the developer has the choice to use the Extension Methods or not. This can easily be explained with an example utility method:

C#
public static string CutEnd(string input, int length)
{
     if (IsEmpty(input)) return input;
     if (input.Length <= length) return string.Empty;
     return input.Substring(0, input.Length - length);
}

and here is my Extension Method:

C#
public static string CutEnd(this string input, int length)
{
     return Utils.Strings.CutEnd(input, length);
}

This gives the developer the freedom he/she wants, whereby the Extension Method or the static method can be used. Also, only one set of tests needs to be done for both methods.

Strange Behavior

Now, I would have thought that creating an Extension Method that checks for nulls is pretty pointless. My thinking was: "how could I check for null if the object is null - won't I get a NullReferenceException?" Well, I tested it, and apparently no - you won't get the exception. Here's the Extension Method:

C#
public static bool IsNullOrEmpty(this string input)
{
     if (input == null) return true;
     return input.Length == 0;
}

Here's some code to test it:

C#
string str = null;
if (!str.IsNullOrEmpty())
{
     Console.Write(str);
}

This code runs fine - no problems! Very strange indeed, but at the same time, useful. More can be read about this at http://diditwith.net.

Testing Extension Methods

When developing any code that will be reused again and again (including Extension Methods), writing tests for that code becomes a necessity. This is to ensure the code is both reliable and bug free. When creating a reusable framework that is reused on every project and also likely to change a number of times in its lifetime, testing becomes an absolute requirement! The only smart way to utilize these types of tests is by writing Unit Tests. Unit tests allows you to keep a set of tests that you can run at any time, over and over again, to check for all use-case scenarios. So, when you make a change to a utility method, run the unit tests for that method to make sure it still does what you expect. There are many unit testing frameworks out there, including NUnit which is an Open Source framework written in C#. You can also purchase and/or download add-ins for Visual Studio to allow for unit testing within the IDE, but these are no longer required. There is now built-in Unit Testing functionality in VS2008 Pro. Woohoo!

Unit Testing in VS2008 Professional

With a few simple clicks of the mouse, you can create unit tests for code that you have written. Let's do that for our Extension Method:

  1. Click the Test menu, then 'New Test'.
  2. Select the 'Unit Test Wizard' option and click OK.
  3. Unit Test Wizard

  4. Enter the name of your new test project.
  5. Select the methods you wish to test and click OK.
  6. Select Methods

It's that simple! We have now created a new project called UtilsTests that contains all our tests for the Extension Methods we just created:

Unit Test Project

Now all you need to do is customize the tests to suite your needs. Here is the generated test code:

C#
/// <summary>
///A test for ToSomethingElse
///</summary>
[TestMethod()]
public void ToSomethingElseTest()
{
     string input = string.Empty; // TODO: Initialize to an appropriate value
     string expected = string.Empty; // TODO: Initialize to an appropriate value
     string actual;
     actual = JunkExtensions.ToSomethingElse(input);
     Assert.AreEqual(expected, actual);
     Assert.Inconclusive("Verify the correctness of this test method.");
}

As you can see, it intelligently looks at the input parameters of the method and generates the test for you. All you need to do now is change the input and the expected output, then remove the Assert.Inconclusive line, add a few tweaks, and you have a working unit test. This is what the test should look like now:

C#
[TestMethod()]
public void ToSomethingElseTest()
{
     string input = "abc123";
     string expected = "      abc123";
     string actual = input.ToSomethingElse();
     Assert.AreEqual(expected, actual);
}

Obviously, a unit test is only as good as the coder who wrote it, so make sure your unit tests are extensive. Actually, be more extensive than you usually would, and take into account even the simplest cases. In fact, be paranoid when you write your unit test. This way, you will be sure your tests cover every angle.

Now run your tests by clicking Test > Run > All Tests in Solution:

Run your Unit Tests

..and see the result in VS2008:

Unit Test Results

As you can see from the screenshot, not all our tests passed. We now need to delve into the code and see why. So, like you would normally do as a VS developer, place a break point into your failed test code. But this time, instead of just running your tests, choose to run them in Debug mode by clicking Test > Debug > All Tests in Solution:

Debug Unit Test

Now you can step through your code and see why the test is failing:

Debugging a Unit Test

Conclusion

So we have run through a very simple example of what Extension Methods are and how to write unit tests to test them. I hope this article has created some interest in the new features available in VS2008, as they have dramatically helped me code smarter. I use the unit test features daily with my new utilities project written for the .NET Framework 3.5. For example, every day I seem to change or add functionality to my string utils class, and what better way to know and trust that my changes work than by having a set of unit tests that I can run at a click of a button.

Go check out my String Utils class written in .NET 3.5 with a few handy Extension Methods. There you can download the source which includes the full unit tests for the methods.

History

  • 4 Nov. 07: Version 1 submitted.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Web Developer
South Africa South Africa
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralStatic Utility Method and Extension Methods Pin
BigPMcCoy18-Jun-08 7:04
BigPMcCoy18-Jun-08 7:04 
Questionwhat are the risks with extending a class with additional methods Pin
Alexis Rzewski7-Jun-08 0:59
Alexis Rzewski7-Jun-08 0:59 
AnswerRe: what are the risks with extending a class with additional methods Pin
BigPMcCoy18-Jun-08 9:32
BigPMcCoy18-Jun-08 9:32 
GeneralUnit testing in VS2008 Pin
si6186-Nov-07 13:25
si6186-Nov-07 13:25 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.