Wednesday, 17 February 2010

Resx Resource Problems when Unit Testing

If you use resx files for something like translations in your web apps, you'll notice problems when unit testing as your web app won't be running in its natural state and those resources won't be loaded as normal. Typically you'll get the error...

Could not load file or assembly App_GlobalResources


I'm yet to find a decent solution for this problem but here's how I currently get around it in MVC apps. Here I'm replacing my dependency on Strings.resx in App_GlobalResources.

First thing to do is to create a ResourceManager property and make use of this instance within the class you're testing. Now whenever you need to make use of the resource you have to replace the normal syntax of Strings.FieldYouWant with StringsResource.GetString("FieldYouWant") as shown in the method MethodBeingTested().

public class MyController
{
   public ResourceManager StringsResource
   {
      get;
      private set;
   }

   public MyController()
       : this(Strings.ResourceManager)
   {}

   public MyController(ResourceManager stringsResourceManager)
   {
      StringsResource = stringsResourceManager;
   }

   public object MethodBeingTested()
   {
      return new ContentResult( StringsResource.GetString("FieldYouWant") );
   }
}

In your test project you'll need to create a Strings.resx mirrored source file and make use of this when testing MyController class. Do this by instantiating with a resource from the calling test assembly...

var stringsResource
   = new ResourceManager("test.assembly.Strings", Assembly.GetExecutingAssembly());
var controller = new MyController(stringsResource);
...not pretty, but at least you can run your unit tests without an exception slapping you around the face. Any one got a better solution?

Tuesday, 16 February 2010

Using Analytics to Track Events & AJAX Navigation

Google Analytics is THE way to record and analyse everything about the traffic on your site. Whilst it's real easy to setup you need to change the default behaviour if you want to record javascript events and AJAX navigation changes; this is how to do exactly that.

Analytics requires two things to work. You need the Analytics resource on the client...

<script type="text/javascript">
   var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
   document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
</script>
...and call the tracker with your unique ID (provided when you sign up)...
<script type="text/javascript">
   try {
      var pageTracker = _gat._getTracker("123456789");
      pageTracker._trackPageview();
   } catch (err) { }
</script>
...it's the pageTracker._trackPageview(); part that sends the data to Google Analytics. Without parameters the current URL is sent. However, you can override the default behaviour and pass the URL as an argument.

So change the second part to...

<script type="text/javascript">
   try {
      var pageTracker = _gat._getTracker("123456789");
   } catch (err) { }
</script>
...then you can call pageTracker._trackPageview('/My-Virtual-URL'); with your 'virtual' URLs at will - perfect for recording javascript events and AJAX navigation changes :)

Wednesday, 10 February 2010

Hudson as an Alternative to TFS

I've been looking at alternatives to Team Foundation Server for my latest project's continuous integration tool... and I think I've found it!

Hudson was suggested to me by a colleague (Jonathan Relf) after his attempts with Cruise Control became a little frustrating.

You'll have Hudson installed and building your projects in under an hour unless you're stupid or get carried away with the large number of plugins, including a Chuck Norris plugin ;)

Someone has too much time on their hands...

I particularly enjoyed...

  • VERY easy to setup
  • LOADS of plugins
  • Setup, monitioring and configuration is all through a nice web based interface

I'll keep you posted with how I get on.