![]() |
Languages »
C# »
General
Beginner
License: The Code Project Open License (CPOL)
Extension Methods and Unit Testing in VS 2008By Brad VinCreate some useful extension methods using .NET 3.5, then test your new methods using the built-in unit testing functionality in VS 2008 Professional. |
C# 3.0, Windows, .NET 3.5VS2008, Dev, QA
|
||||||||
|
Advanced Search |
|
|
|
||||||||||||||||

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.
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.
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.
An extremely simple (and useless!) example of an extension method can be seen by the following code :
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:
using Utils.MyExtensions;
...and your new extension method is now available to you, as you can see in the intellisense:
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.
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 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. In 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:
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:
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.
public static bool IsNullOrEmpty(this string input)
{
if (input == null) return true;
return input.Length == 0;
}
Here's some code to test it :
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
When developing any code that will be reused again and again (incl. 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 it's 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 VS 2008 Pro. WOOHOO!
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 :



/// <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:
[TestMethod()]
public void ToSomethingElseTest()
{
string input = "abc123";
string expected = " abc123";
string actual = input.ToSomethingElse();
Assert.AreEqual(expected, actual);
}
Obviously, a unit test is as only 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.
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 ver 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 full unit tests for the methods.
4 Nov 07 : Version 1 submitted
| You must Sign In to use this message board. | |||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||
General
News
Question
Answer
Joke
Rant
Admin
|
PermaLink |
Privacy |
Terms of Use
Last Updated: 4 Nov 2007 Editor: |
Copyright 2007 by Brad Vin Everything else Copyright © CodeProject, 1999-2009 Web17 | Advertise on the Code Project |