Chris Canal

A Scottish .NET Developer

  Home  |   Contact  |   Syndication    |   Login
  23 Posts | 0 Stories | 17 Comments | 0 Trackbacks

News

Twitter












Archives

Post Categories

Thursday, May 15, 2008 #

Recently I’ve been working a lot with the new ASP.NET MVC framework, with Preview 1 (bleh) and the interim drop, Pre-Preview 3?
The ActionResult is a fantastic addition, making the framework far easier to test. However, I noticed I was basically doing the same thing for each test:
  1. [Test]
  2. public void TestSomething()
  3. {
  4.    var actionResult = controllerUT.Something() as RenderViewResult;
  5.  
  6.    If ( actionResult == null )
  7.       Assert.Fail(“ActionResult was null.”);
  8.  
  9.    Assert.That(actionResult.ViewName, Is.EqualTo(“ViewName”));
  10.    Assert.That(actionResult.ViewData, Is.Typeof(typeof(SomeClass)));
  11.    Assert.That(((SomeClass)actionResult.ViewData).SomeProperty, Is.EqualTo(123));
  12. }
Basically asserting the view name, view data type and maybe asserting a property or two on the view data. In the spirit of treating the test code as a first class citizen I decided to refactor out the duplication. The resulting refactoring turned the above into the following:
  1. [Test]
  2. public void TestSomething()
  3. {
  4.    controller.Something().AssertViewName(“ViewName”).AssertViewDataType<SomeClass>(c => Assert.That(c.SomeProperty, Is.EqualTo(123));
  5. }
Which I personally think is alot nicer! Although I'm a little biased, so I thought I would share it and see what other people thought of it. Below is the code I came up with. Any and all suggestions (good or bad) are appreciated
  1. namespace e4umsMN.Spec.Utils
  2. {
  3.     using System;
  4.     using System.Web.Mvc;
  5.     using NUnit.Framework;
  6.     using NUnit.Framework.SyntaxHelpers;
  7.  
  8.     internal static class ActionResultHelper
  9.     {
  10.  
  11.         #region Public statics (6)
  12.  
  13.         public static ActionResult AssertActionRedirect(this ActionResult actionResult, string actionName)
  14.         {
  15.             return actionResult.AssertNotNull<ActionRedirectResult>(arr => Assert.That(arr.Values["action"], Is.EqualTo(actionName)));
  16.         }
  17.  
  18.         public static ActionResult AssertHttpRedirect(this ActionResult actionResult, string redirect)
  19.         {
  20.             return actionResult.AssertNotNull<HttpRedirectResult>(hrr => Assert.That(hrr.Url, Is.EqualTo(redirect)));
  21.         }
  22.  
  23.         public static ActionResult AssertRenderViewResult(this ActionResult actonResult, Action<RenderViewResult> extraAssert)
  24.         {
  25.             return actonResult.AssertNotNull(extraAssert);
  26.         }
  27.  
  28.         public static ActionResult AssertViewDataType<T>(this ActionResult actionResult, Action<T> viewDataAssert)
  29.         {
  30.             return actionResult.AssertRenderViewResult(a => viewDataAssert((T)a.ViewData));
  31.         }
  32.  
  33.         public static ActionResult AssertViewDataType<T>(this ActionResult actionResult)
  34.         {
  35.             return actionResult.AssertRenderViewResult(a => Assert.That(a.ViewData, Is.TypeOf(typeof(T))));
  36.         }
  37.  
  38.         public static ActionResult AssertViewName(this ActionResult actionResult, string viewName)
  39.         {
  40.             return actionResult.AssertRenderViewResult(a => Assert.That(a.ViewName, Is.EqualTo(viewName)));
  41.         }
  42.  
  43.         #endregion Public statics
  44.  
  45.         #region Other statics (1)
  46.  
  47.         private static T AssertNotNull<T>(this object actionResult, Action<T> extraAssert)
  48.         {
  49.             if (actionResult == null)
  50.                 Assert.Fail("ActionResult was null");
  51.  
  52.             extraAssert((T) actionResult);
  53.  
  54.             return (T) actionResult;
  55.         }
  56.  
  57.         #endregion Other statics
  58.  
  59.     }
  60. }

Friday, May 09, 2008 #

Quote:
...legacy code is simply code without tests. - Working Effectivly with Legacy Code - Micheal Feathers

I was discussing testing with a friend the other day, mainly Test Driven Development and we got onto the topic of new code without tests and retrofitting them. The first thing that popped into my head was the above quote and the following:

Quote:
Code without tests us bad code. It doesn't matter how well written it is; it doesn't matter how pretty or object-oriented or well-encapsulated it is. With tests, we can change the behaviour of our code quickly and verifiably. Without them, we really don't know if our code is getting better or worse.
You can imagine his reaction after I shared this with him.

However, I completely agree with that Micheal is saying. Any code without tests, no matter if it was written a few hours ago or a year, is bad legacy tests. Retrofitting tests on the code then becomes a task with dealing with legacy code. True, you will probably not have as hard a time dealing with new legacy than you would older legacy code, but the main issue is that your still dealing with legacy code.

Once the code is written, retrofitting tests isn't Test Driven Development. Your not designing the code to make your tests pass, your designing you tests to ensure behaviour of exisiting code, and this means legacy code. Would I recommend retrofitting tests? No, I would give it a miss, concentrate more on integration testing. Add unit tests on the code when your editing it, as you would with, you guessed it, legacy code.

My Code isn't bad because it doesn't have tests!
It was never my intetion to insult friend, but the fact still remains that I agree with the above quote and view any code without tests as bad code. The key aspect of a good application is not how cool the code or how slick he UI is, but how maintainable it is. And not maintainable for you, but the developer after you.

Over the years I've worked on some really nice applications. The UI is nicely design, the customers are happy with how everything works, but without tests, maintaining it is magnatidues more difficult than an application that does.

How can a new developer to an applicaton confidently make changes if there is nothing to verify the changes? Sure, they can sit and manually test the UI is doing as it should, but what about the subtle bugs that can be introduced? The side affects of a change that can appear somewhere else in the application. I've experienced nasty side-affects without tests before, and when they are in an unrelated section of the code, it can be a nightmare without to track down.

Un-legacying your code
As I said before, there isn't much point in retro-fitting tests as an actual task. Concentrate on adding tests whenever your going to be working on an area. The goal is to introduce confidence building tests and either maintain behaviour when refactoing, or ensuring you don't break anything when changing behaviour.

Without TDD, your probably going going to have to break dependencies. The one common issue I've come across when helping people deal with legacy code is dependencies and interaction with the database. if your test hits an external resoruce, then its not a unit test. A unit test should be small, quick to run, atomic and run is isolation. This makes it difficult to add tests to code that uses things like LINQ to SQL as they are very tightly coupled to the database, trying getting a test quickly and easily in a test harness. Anything that ties your application to a data source is not a good option for maintanability.

It's also detrimental to running the tests. Having tests that hits the database can be time consuming, time consuming tests == test that will probably not be ran and then your back to writing legacy code.

Errr... the point?
So, the point? Well, learn TDD. I know I do keep going on about this, but I do have a good reason. TDD is new to .NET, it needs more people to take it up. Microsoft has just started with the MVC Framework, so momentum is growing. But it's the troops out in the field that need to pick it up too. Trust me, when you get into the full swing of it coding is exteremly fun again, even the boring tweaks. You've always got a safety net so huge refactoring or changes hold no fear, late requirements from a client are no longer a reason to moan or a worry.

Tuesday, May 06, 2008 #

Developer Day Scotland

I'm attending this weekends Developer Day Scotland in Glasgow and I'm trying to organise an ALT.NET meet/Open Spaces.  I've left it really really late, but hopefully I'll be able to get something together.

When I say "I'll", I'm hoping this will soon be "we'll".  So, any other ALT.NETters attending DD and interested in having a short session?  Colin, one of the organisers, has been kind enough to offer a room over lunch for it.  If your attending and your not sure what ALT.NET is, feel free to join in, the more people the better.  Yes, I am worried about sitting in a room myself for a hour!

If you are an ALT.NETer, please contact me if you want to help out or host/suggest something.  Email me at chris dot-thing canal at-thiny e4ums another-dot co and-another uk

 




As you may or may not have seen, a few people have been blogging about Professional ASP.NET 3.5: In C# and VB on Amazon.com being $16.  Being in the UK, I thought I would check it out.  Turns out its just as cheap: http://www.amazon.co.uk/Professional-ASP-NET-3-5-VB-Programmer/dp/0470187573/ref=sr_11_1?ie=UTF8&qid=1210067583&sr=11-1

I've just ordered mine :)

Thursday, May 01, 2008 #

I'm trying to deploy an SSIS task onto a server and I'm getting the following error:
The task "script task" cannot run on this edition of Integration Services. It requires a higher level edition
The task in question is a Script Task and the SSIS package is loaded from the file system and executed with C#. It connects to a spreadsheet and retrieves the first worksheets name. It works fine locally but not on the server. The version of SQL Server installed is Enterprise Edition.

I didn't write the package, my development manager did and he's on holiday for 2 weeks and the client is in tomorrow.

Has anyone came across this? It's possibly my fault, I haven't really worked with SSIS before. I'm now going to have to replicate what the script does in C#, so any suggestions that saves me from doing so will be greatly appreciated!

Wednesday, April 23, 2008 #

Scott Hanselman has been spending some time making an interesting ALT.NET Greek Code Generator.  Just check some boxes and create your very own ALT.NET Geek badge, now in Silverlight!

Get Microsoft Silverlight

I've just upgraded to the latest version interim drop of the MVC framework and MVC Contrib (which I can't seem to build from source using NAnt...).  Everything appeared to be ok, except for one thing: a controller action that uploads a file was now throwing an error:

cannot convert from 'System.Web.HttpPostedFileBase' to 'System.Web.HttpPostedFile'

After a few seconds of confusion I quicky dawned on me that this might be a very good thing.  A quick look at the System.Web.Abstractions confirmed my throughts, it now contained abstractions for HttpPostedFile and HttpFileCollection!

Color me happy, the only code I couldn't get covered was Actions that handled file uploads.


Have all your Desgin Pattern woes solved and more: http://uncyclopedia.org/wiki/Design_Patterns

As a general rule of thumb, keep in mind that your code instantly gets 270-890% better when using design patterns (unless, of course, you are programming in Perl or Assembly). Note also that design patterns let you score big time with the ladies at parties (unless you abuse Dependency Rejection pattern), increase the size of your member, make you a better driver, and level you directly to OT9.

Made my chuckle!

On a totally different note, now long till Developer Day Scotland.  If your in Scotland and have signed up, shame on you!  Get signed up now, should be an interesting day.  Also, like to point out the Scotland ALT.NET User Group again.  Looks like a meet on the 28th May is set to g oahead.  I'm due to be on holiday then, so I'm not going to make it, but I'm really looking forward to attending future events.  I think raising the developer education level in Glasgow is really long past due.  There are too many developers out there that take the word of Microsoft as gospel won't try any of the fantastic OSS projects out there!


Tuesday, April 22, 2008 #

Looks like there is going to be a meetup on the 28th of May for the Scotland ALT.NET User Group.  Unfortunately I might be on holiday  so I won't be there! :(  If your interesting in participating, check out the mailing list.

Looks like it will be an informal meet up in Waxy O'Conner as a precursor to a more formal meetup.  I'm keen on getting an Open Space conference going like what took place in Seattle at the weekend.

Monday, April 21, 2008 #

My dev manager has decided he has had enough of the terrible level of development education in Glasgow, so he's wanting to start a Glasgow ALT.NET User Group.

It's not a job requirement for me to join, so I'm there.  If your in Scotland and you want to discuss ALT.NET with other Scotland based develoepers, be sure to sign up.  He posted on Scottish Developers  and you can sign up for the mailing list here: http://tech.groups.yahoo.com/group/glasgow_altdotnet_usersgroup/