Archive

Archive for April, 2008

Avoiding the D’oh (aka assumptions are bad)

April 21, 2008 Leave a comment

I’ve just had one of those d’oh moments, if only I had written a unit test for 1 simple constructor I would have saved myself about 3 hours of pointless frustration.

I am currently integrating NHibernate into my current project, which basically means I am writing a lot of mapping files. Having never used NHibernate before I don’t have that invaluable store of wisdom built up from previous implementations – so I am relying on some very simple unit tests to make sure my mapping files are correct.

The problem came about when I was trying to map a collection of value types (EmploymentDetails) that hold the details of the entities (Employee) employment history over time (essentially what store they worked in when).  While I was looking at the domain object I realised I could clean it up a little and make it express the intent more correctly as well as a little more efficiently, so I quickly hacked together the changes and carried on building the mapping file – BIG MISTAKE.  No tests were written, it was only a simple rename and move a couple lines of code around in the constructor right?  WRONG.  I forgot 1 crucial line of code and that just cost me about 3 hours chasing what I thought was a problem in the mapping file, when it was actually a problem in the code.

Integrating a new technology (defined as one you have no prior experience with), is a high risk exercise.  The simplest way to reduce risk is to change as little as possible and make sure it works.  Unit testing allows you to follow this cycle easily, but you have to commit to it completely, otherwise the value of your investment is significantly reduced – you get a false sense of security about the state of your code and build on those assumptions.

It’s also wise to remember that no matter what – you are a terrible coder and should therefore check ALL your assumptions that your current problem is built on before trying to solve the problem – sometimes it is incredibly useful to assert these as preconditions for your test – just so you really are sure your assumptions are correct.

Lesson learned, I’m off to retrofit a test or 2 :)

Categories: TDD

MonoRail and Castle Validator

April 14, 2008 Leave a comment

Recently I have been working to add validation to a web application I am building using MonoRail. A bit of research turned up a brilliant component created by Hammett that greatly simplifies adding client and server side validation in one place.

Hammett’s validation components work within the scope of the databinding operation that allows you to bind form fields directly into parameters in a reasonably seamless manner. You do need to be able to apply validation attributes to properties in the object being bound, so it does not appear that you can validate simple parameters, but I am using a presentation model for a majority of my forms so this was not a problem.

There is a great guide here and Hammett’s screencast here that show you how to set up the validation.

There are a couple of gotchas with the validation though, and these repeatedly tripped me up until I understood what was going on, so I will publish them here and hope that it helps someone else (all of these problems appear when doing server side validation only – I have deliberately disabled the client side validation until the server side validation is complete and correct):

Validation of simple properties happens before the value has been converted. This means the validator gets passed a string value and therefore does not always behave as expected. For example ValidateNotSameValue(CallResult.Unspecified) passes validation when a value of Unspecified is submitted because it compares Unspecified (the enum value) with “Unspecified” (a string value). My solution at the moment is to write type specific validators that extend ValidateNotSameValueAttribute and convert the value to a string that is passed to the validator (like this NotSameEnumValueValidator).

Validation only occurs if a value for the field is sent in the request. If no value is set, then the validation for that property is not triggered. For example I have a property called QuestionnaireId which must not be empty, this rule is enforced using a custom validator that ensures the value is a Guid and is not equal to Guid.Empty. The validator works (it is used in a number of other places), however it will not ensure a value is selected from a radio button group as no value is posted to the server for that form field (the databinder explicitly skips validation if there is no value to bind). I have not worked out a strategy for dealing with this yet.

I think Hammett has done a great job, and this component covers the basic scenarios as well as providing a good extensibility mechanism, however there are a few gotchas (even Hammett outlines a few here), the key is to be aware of what is happening and why.

Categories: MonoRail
Follow

Get every new post delivered to your Inbox.