# Friday, June 27, 2008

It always amazes me when I find some little gem of functionality in a code library that I've used for some time.  Today I was amazed to find out that RhinoMocks has a logging facility built into it, and I'm willing to bet this feature has been there for a long time and I just never noticed it.

Turning on RhinoMocks logging in your test fixture setup (or test) outputs all kinds of nifty informational messages about what RhinoMocks is doing.  There appears to be 3 built in loggers in RhinoMocks:

  • TraceWriterExpectationLogger
  • TraceWriterWithStackTraceExpectationWriter
  • TextWriterExpectationLogger

Here's a simple test case using TraceWriterExpectationLogger (line 4):

   1: [Test]
   2: public void Should_login_user_with_valid_user_name_and_password()
   3: {
   4:     RhinoMocks.Logger = new TraceWriterExpectationLogger();
   5:  
   6:     var userRepository = MockRepository.GenerateStub<IUserRepository>();
   7:     userRepository.Stub(x => x.GetUserByUserName("sneal")).Return(new User
   8:     {
   9:         UserName = "sneal",
  10:         Password = "password"
  11:     });
  12:  
  13:     var controller = new LoginController(userRepository);
  14:     controller.Login("sneal", "password");
  15:     
  16:     Assert.AreEqual("sneal", controller.UserContext.UserName);
  17: }

You might have noticed I'm using the new AAA syntax in RhinoMocks 3.5.  Very elegant.  No setup method, no explicit replay or verify calls.  I really like it.

Using the TraceWriterExpectationLogger looks like this from the ReSharper test runner, notice the trace messages from my mock:

image

So the next time you get stuck with an over complicated test session, try turning the logger on - I know I will.

Friday, June 27, 2008 5:01:21 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
# Tuesday, June 10, 2008

Sensitive information on your website should be encrypted between the client and the server, which generally means we need to use SSL (https).  How do we require SSL on specific MonoRail controllers or URLs?

With ASP.NET you could go into IIS and just check the "Require SSL" checkbox for a particular ASPX page.  With MonoRail, or even ASP.NET MVC, there's no corresponding resource on disk for IIS.  So how do we enable SSL at the controller level?

First off you need to add a certificate to your site in IIS, make sure you don't check "Require SSL" at the site level otherwise all requests will need to be over https. Remember we want finer grained SSL settings.

The solution I came up with was to create a MonoRail filter that gets runs before every action on a controller.  This declarative solution using attributes is much better than a base class since it can easily be added or removed from a controller.

   1: public class SecureChannelFilter : IFilter
   2: {
   3:     public const string AppKey = "SecureChannelFilterDisabled";
   4:  
   5:     public bool Perform(
   6:         ExecuteWhen exec,
   7:         IEngineContext context,
   8:         IController controller,
   9:         IControllerContext controllerContext)
  10:     {
  11:         if (context.Request.IsLocal)
  12:             return true;
  13:  
  14:         if (context.Request.Uri.Scheme == "https")
  15:             return true;
  16:  
  17:         bool disabled;
  18:         bool.TryParse(ConfigurationManager.AppSettings[AppKey], out disabled);
  19:         if (disabled)
  20:             return true;
  21:  
  22:         context.Response.StatusCode = 403;  // access forbidden
  23:         return false; // don't continue with request
  24:     }
  25: }

As you can see from the code, the filter allows local requests through without SSL but requires SSL for all other requests unless the filter has been configurationally disabled.  This allows us to run without SSL on our local development boxes.

If a request requires SSL and is not coming in over SSL, this filter then returns a 403 (Forbidden) status code which will then end up showing the IIS 403 error page.  If you wanted to get real fancy you could change your 403 error page to just redirect you back to the requested page, but using https instead of http.

To require SSL for a particular controller, like lets say a credit card controller, we would add the Filter attribute specifying the SecureChannelFilter:

   1: [Filter(ExecuteWhen.BeforeAction, typeof(SecureChannelFilter))]
   2: public class AccountDetailController
   3: {

With that in place we can feel confident that our controller will not be viewable without SSL.

Tuesday, June 10, 2008 7:31:41 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [2]  | 
# Thursday, June 05, 2008

My combination of a Microsoft USB Natural Ergonomic Keyboard 4000 and a Microsoft USB Dual Receiver Wireless Mouse was causing my PC to immediately wake after hibernating.  This was also causing S4 sleep mode in Vista to fail to wake up.

Normally the wireless mouse has a wireless keyboard as part of the package, but I'm only using the mouse so I think this was causing problems - my device manager showed two keyboards even though I only have one wired keyboard.

To fix this I ended up disabling both the keyboard and mouse (receiver) from being able to resume the PC.  You can do this using the command line tool powercfg.  Here's what I did:

powercfg -devicedisablewake "Microsoft USB Natural Ergonomic Keyboard 4000 (IntelliType Pro) (001)"

powercfg -devicedisablewake "Microsoft USB Dual Receiver Wireless Keyboard (IntelliType Pro) (001)"

 

You can verify the device are disabled using: powercfg -devicequery wake_armed

 

After disabling both of those, S4 and hibernation started working again.

Thursday, June 05, 2008 5:11:43 AM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [1]  | 
# Tuesday, June 03, 2008

Over the years I've struggled with naming conventions for unit test methods, picking up various habits from different projects and people.  Roy Osherove (who reminds me of Adam Sandler) at one point recommended the following format for your unit test names:

[MethodName_StateUnderTest_ExpectedBehavior]

Although workable, and certainly an improvement over chaos, I don't find it all that appealing.  Non-programmers probably won't get it, and even programmers might have to read it a couple of times - at least that's what I ran into.  It does organize a group of tests in a fixture nicely, but beyond that...  its just not for me.

I've tried varying other methods, but I've generally always started my test names with some sort of assertion like "Should" or "Can".  This makes the test at least state what the expected behavior that is supported in a semi-fluid way.

Beyond that I like my unit test method names to convey exactly what is being tested, not just the class or method name being tested along with a state - I want a full sentence describing the expected behavior.

Up until recently I've been following the .NET naming conventions for my unit tests, but the simple fact is my method names are too long to be readable sentences.  You see, my test method names tend to be sentences which may or may not come from the user story or task itself. 

Here's an example method name from my current project using the .NET naming conventions: ShouldRedirectToShippingPageWhenShippingIsRequiredAndShippingAddressIsMissing.  Not only is this long, but its also unreadable except to programmers.  Even to programmers this isn't pretty, its just too long.

Now here's how I've been formatting my test names as of recent:

image

Obviously I'm breaking .NET naming conventions left and right here, but I don't care who you are, that's waaaaay more readable. Even more importantly I can discern what the test does just by reading the method name.  I find this handier than reading comments since it also shows up in your test runner. 

There's little need to go back through and re-read the test itself to figure out what the test does, its clearly stated in the method name. With this style anyone can go back and read the unit test method name and figure out the expected behavior.

I've never been too happy with the .NET naming standards especially in regards to unit tests.  The world is bigger than .NET, so take that convention!

Tuesday, June 03, 2008 6:11:51 AM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [1]  | 
# Monday, June 02, 2008

I spent most of the day reading the language tutorials for Boo after realizing that an internal DSL for discounts and promotions would be one giant leap forward in our e-commerce web front end.  Unfortunately as a side affect of spending most of the day learning just how flexible Boo is, C# has lost a lot of its luster to me.  Boo is a fantastic language (more on that another day), but C# still has ReSharper and Visual Studio on its side.

Scratch that, Boo now has Visual Studio support too!

It seems for any language in the .NET world to gain wide acceptance it must first be integrated tightly with Visual Studio.  With BooLangStudio Boo becomes a first class .NET language.  Currently BooLangStudio is under early development, and as such it has a ways to go to become comparable to the VS C# experience, but despite the rough edges, its very usable.  I did run into some issues getting started, all very minor considering how early in development the add-in is.

First off, you need to install the MS Visual Studio 2008 SDK, then finally install the BooLangStudio add-in.  The BooLangStudio add in is installed from the command line by running the "install.bat" file which essentially bootstraps an NAnt build script.

With that out of the way, you start Visual Studio 2008 using the "development hive".  This is done from the start menu from the VS 2008 SDK start menu folder.

image

After which we can create a new boo project using one of the installed templates.

image

Choosing the Boo Console Application creates everything for a "boo hello world" application, as seen here.

image

The nice thing about the .booproj files is that they are MSBuild files just like in C#, which also means they should work in SharpDevelop which includes Boo support.  From my standpoint its important that MSBuild is supported for automated builds and customization.  Once a boo project is created, building and running is simple as hitting F5.

image

image

If you have any compilation errors they show up in the Errors List just like in any other Visual Studio language.

image

The on issue I did have, is with my tab settings for Boo.  Boo uses indentation to track code blocks rather than braces or end statements, so unfortunately it's white space sensitive.   Here's my really "super awesome" Car class that I added to my project.

image

Notice that the syntax highlighting isn't perfect, but that's very minor.  Slightly less minor, to get a new Car class to compile I first had to go into the Visual Studio Tools | Options menu and set the tab spacing for Boo.  Before I did that I was getting odd, "expecting DEDENT" and "expecting INDENT" errors all over the place.

image

Once I set the tab size and re-did the tabbing for my class, everything worked just fine.

image

Boo
Monday, June 02, 2008 5:38:30 AM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  |