Monday, 21 March 2011

Rhino Mocks - Get broken after running test with WCF

I discovered something that might explain why tests sometimes seem to fail after an individual test has failed for no obvious reason.
Often in NUnit, you setup various mocks in [TestFixtureSetup] and then run one or more tests. In [TestFixtureTearDown], these mocks are disposed of. What is important to know is that if an exception is thrown during TestFixtureSetup, the TestFixtureTearDown is NOT called.
What this means is that suppose your mock #1 redirects an endpoint to a locally hosted mock, if you setup mock #1 but while setting up mock #2 an exception is thrown, then mock #1 will not be disposed and this means one of two things might happen. Firstly, when you try and setup the mock again, it might fail on the basis that something is already "listening" at the endpoint it is trying to use. Secondly, if you don't dispose the mock, the endpoint is not reset back to what it should be. In this case, if another test does not use a mock but DOES use the endpoint for something then it will have been left pointing to your local mock site but with nothing listening on it. Your test might then fail because it gets no response to its request.
To avoid all of this, add a catch to your TestFixtureSetup which will call Dispose on all mocks if they are not null in the case of an exception.

Monday, 14 March 2011

CJuiAutoComplete Custom Listing Example

The CJuiAutoComplete in Yii is great but because it uses the standard interface, there is one thing that cannot be done directly with the Yii control, that is customising the list that is displayed when you type something in. In my last example was a simple list that just displayed the label and selected this when you clicked it (and stored an id number in a hidden field) but in my case, I am searching for church names and there would be lots of duplicates so the name of the church by itself is not enough.
There is an 'undocumented' feature of the jQuery autocomplete (which the Yii control uses) which is mentioned on various forums and which can be used to override the default behaviour. It is called _renderItem and which by default only prints the labels. This needs to be 'manually' linked to the jQuery object since it cannot be joined directly to the CJuiAutoComplete and this uses the Yii function registerScript(). Anyway, this is the code I used (see my earlier example for what all the other controls are):
Yii::app()->clientScript->registerScript('custom_church_search','
    $("#churchac").data( "autocomplete" )._renderItem = function( ul, item ) {
 return $( "<li></li>" )
 .data( "item.autocomplete", item )
 .append( "<a>" + item.label + ", " + item.street + ", " + item.city + "</a>" )
 .appendTo( ul );
};');

Most of these names and code I left as per the example because I wasn't totally sure what they were. The only things I changed were the name of the script which is used as a dictionary lookup, the jQuery selector (#churchac) and the line which appends the <a> reference. This by default prints only item.label. In my case, all I did was add some commas and the street and city names. You should retain the <a> tags if you want the arrow keys and such like to work.

Update 

I tried to use this recently and it didn't work (cannot set _renderItem on undefined). I don't know what has changed, it is possibly a timing issue in my code, but a workaround is to modify the _renderItem method for ALL instances of autocomplete by re-defining the main definition instead of only the one for this specific instance. You do this by changing line 2 from:

$("#churchac").data( "autocomplete" )._renderItem = function( ul, item ) {
 
to
 
$.ui.autocomplete.prototype._renderItem = function( ul, item ) { 

Note that since I only apply this script in my controller action for one page, it will only affect the autocomplete control(s) on that one page.

Thursday, 10 March 2011

Windows 7 Gripes

I am generally pleased with Windows 7. It seems to perform well and is generally usable but there are some things that are annoying about it. At the end of the day, an operating system is just a platform to run productivity applications, it should not be any real beast in its own right and should not get in the way.
My biggest complaints are changes. For instance, trying to get into the various options screens of Windows Explorer is horrifically complicated when you are used to the older way of Tools-Options, a fairly universal concept that millions of people were used to. Now they are spread across various unintuitive icons and menus which look like they were 'designed' by a child.
Another thing which I come across a lot is the renaming of standard shortcuts so you can't find them. Most of us were used "Add or Remove Programs" which has now been renamed to "Programs and Features" which doesn't really say much differently except it is now in a different place in the control panel because it starts with P instead of A. Why are people allowed to change these? If you want to mention features, call it "Add or Remove Programs/Feature". When you test these things, you would think somebody would notice and complain.

Thursday, 3 March 2011

metadata file xyz could not be found

I got loads of errors like this in a VS2008 project the other day. It seemed really confusing since these errors related to files I had not even touched.
It turned out that a dependent project had not been built - which had not stopped the solution building - which meant the project references of other projects had nothing to reference and therefore could not find the metadata.
Looking up the output window to the first error showed what actually caused the problem and fixing this, got rid of the cascaded errors.