We’re doing some Silverlight development at work and I’m doing some off to the side. I like to stick with a familiar, proven unit test framework. NUnit 2.5.1. has some great new attributes to use during testing (actually these came out in 2.5) such as Timeout and MaxTime. To take advantage of them you have to have a version of NUnit compiled as a silverlight library or at least recompiled referencing the core of silverlight (system.dll and mscorlib versions 2.0.5.0).
In the spirit of continuing what a few other people have done, I have compiled the latest version of the NUnit framework into a SL library and want to make it available. The work of the following guys has helped me use NUnit up to version 2.4 and helped me get 2.5.1 going as well!
A nice template that included the SL framework version, if someone wants this updated please let me know and I can do that too, otherwise I’ll just post my dlls:
http://weblogs.asp.net/nunitaddin/archive/2008/05/01/silverlight-nunit-projects.aspx
A set of instructions to port the framework to SL (I diverged on some of these, see below):
http://www.jeff.wilcox.name/2009/01/nunit-and-silverlight/
Here is the list of changes and what didn’t make the cut:
Not using a ubiquitous language when developing an application is incurring yet another form of design debt, the overhead involved in manual testing is similar to the overhead incurred in translating between separate languages when conversations between users/domain experts and developers occur. Like with foreign languages, idiomatic assumptions and other misunderstandings are likely to fall short of a true conversation, so just pony up and focus on using a COMMON LANGUAGE as Eric Evans refers to in DDD.
Me
Code reuse is very important for developers, most of the patterns and refactorings exist soley to reduce the smell of duplicated code. Null checks are one of the biggest culprits of duplicated code. It is also, to a degree, a concern that often gets scattered through out an application and isn’t properly separated. Without testing and/or good documentation, it’s often hard to determine the expectations of a method that returns a reference type or a nullable value type. Often, unnecessary, paranoid, null checks are incorporated to deal with the problem.
The null object pattern almost solely exists as a pattern to reduce code, so if it cannot reduce the amount of code you are writing, don’t use it!
The idea is that instead of setting a refernece type to null initially, you set it to an implementation of the type that executes “null behavior” if methods are called on it’s contract that would normally throw a null reference exception.
Pros
Say we have a contract for a type:
public interface IThing { void Do(); bool Execute(); }
and your system made a large number of calls to this Do method but had to check if the Thing was null before calling Do/Execute, you could replace the initial value of a reference to it with a Null implementation instead, then if someone calls a method on a null instance it won’t have any side effects (including null reference exceptions) if it wasn’t initialized already.
public class NullThing : IThing { public void Do() { } public bool Execute() { return true; } }
Then, anywhere that used this type could initilize to the NullThing:
public class ThingHaver { private IThing _Thing = new NullThing(); public IThing Thing { get { return _Thing; } set { _Thing = value; } } }
What would be really cool is if we could somehow overload the default operator in c# and set what it returns. Then, if we used an abstract base class of IThing (ThingBase), we could implement this to return our NullThing(), assuming that behind the scenes the compiler relied on wiring up calls to default whenever it ran across:
private ThingBase _Thing;Then we wouldn’t even have to set our variable to NullThing! Though maybe I’m getting too far off on a tangent here :) My one concern with this pattern is that it is very easy to produce a disparity in a team if they all aren’t aware of the pattern or it’s implementation in a particular scenario.
-Wes
Program to an interface, not to an implementation
Not sure if this has a source, but it’s a great concept.
This refactoring, again from Refactoring to Patterns, reduces ambiguity in methods that have too much detail or conditional logic to quickly comprehend. By breaking a method down into smaller methods, the ambiguity can be removed.
The mechanics of this refactoring are rather subjective, but obviously lead to the use of Extract Method. Study the code and make sure you understand it, the longer this takes, the more you need to apply this refactoring! Clean up the code, look for unused or duplicated pieces. Then, extract detail to smaller methods. Reveal intention through naming of new variables and methods. Once you are done, make sure all the code in the Composed Method is of the same level of detail.
Pros
So I rummaged around in some code and stumbled upon a text box validation method that was a great candidate for this refactoring:
public virtual void Validate() { IsValid = true; if (Visible && Enabled) { if (IsRequired) { if (String.IsNullOrEmpty(Text) || Text.Trim().Length == 0) { ErrorMessage = String.Format(Messages.TextBoxCannotBeEmpty, InvalidDisplayName); IsValid = false; } }The level of nested conditionals makes it rather hard to follow. First, I want to remove some of the nesting by returning immediately if the validation isn’t applicable:if (MaxLength != 0 && !String.IsNullOrEmpty(Text) && Text.Trim().Length > MaxLength) { ErrorMessage = String.Format(Messages.TextBoxExceedsMaximumLength, InvalidDisplayName, MaxLength); IsValid = false; } if (MinLength > 0 && (String.IsNullOrEmpty(Text) || Text.Trim().Length < MinLength)) { ErrorMessage = String.Format(Messages.TextBoxUnderMinimumLength, InvalidDisplayName, MinLength); IsValid = false; }
} }
public virtual void Validate() { IsValid = true; if (!Visible || !Enabled) { return; } if (IsRequired) { if (String.IsNullOrEmpty(Text) || Text.Trim().Length == 0) { ErrorMessage = String.Format(Messages.TextBoxCannotBeEmpty, InvalidDisplayName); IsValid = false; } }Next, I notice 3 different “sub validations” occurring. One validates if the field is required, the next validates the maximum length and the last validates the minimum length. Each of these can become their own methods:if (MaxLength != 0 && !String.IsNullOrEmpty(Text) && Text.Trim().Length > MaxLength) { ErrorMessage = String.Format(Messages.TextBoxExceedsMaximumLength, InvalidDisplayName, MaxLength); IsValid = false; }
if (MinLength > 0 && (String.IsNullOrEmpty(Text) || Text.Trim().Length < MinLength)) { ErrorMessage = String.Format(Messages.TextBoxUnderMinimumLength, InvalidDisplayName, MinLength); IsValid = false; } }
public virtual void Validate() { IsValid = true; if (!Visible || !Enabled) { return; }Finally, I realize the level of detail isn’t uniform, I should extract a new property to check if the control is in use. Also, even more troublesome, the intentions of the first line to set the IsValid to true are lost to future developers. This is needed to reset the validation process, otherwise if a control is validated and fails, subsequent calls may still return invalid. My new Composed Method finally becomes:ValidateRequired(); ValidateMaximumLength(); ValidateMinimumLength(); } private void ValidateRequired() { if (IsRequired) { if (String.IsNullOrEmpty(Text) || Text.Trim().Length == 0) { ErrorMessage = String.Format(Messages.TextBoxCannotBeEmpty, InvalidDisplayName); IsValid = false; } } } private void ValidateMaximumLength() { if (MaxLength != 0 && !String.IsNullOrEmpty(Text) && Text.Trim().Length > MaxLength) { ErrorMessage = String.Format(Messages.TextBoxExceedsMaximumLength, InvalidDisplayName, MaxLength); IsValid = false; } } private void ValidateMinimumLength() { if (MinLength > 0 && (String.IsNullOrEmpty(Text) || Text.Trim().Length < MinLength)) { ErrorMessage = String.Format(Messages.TextBoxUnderMinimumLength, InvalidDisplayName, MinLength); IsValid = false; } }
public virtual void Validate() { ResetValidation(); if (!InUse) { return; }The new Composed Method is much easier to comprehend. Ironically enough, looking at other validation methods, the newly extract methods can be re-used either through inheritance or possibly by applying Extract Class. The new InUse property may eventually be exposed for public consumption.ValidateRequired(); ValidateMaximumLength(); ValidateMinimumLength(); } private void ResetValidation() { IsValid = true; } private bool InUse { get { return Visible && Enabled; } } ...