Thursday, February 19, 2009

Rhino Mock Error - rhino mocks requires a return value or an exception to throw

Sometimes it's just a matter of googling the right thing. I was trying to show someone how easy it was to develop mocks to help test, and wouldn't you know it, I kept getting errors in my test harness that I couldn't figure out. I thought it was because we were testing an object with a read only property and using the AutoMockingUnityContainer, but when I was finally smart enough to google the real exception being thrown:

rhino mocks requires a return value or an exception to throw

It immediately led me to this wonderful solution.

Google FTW.

Book Review: Architecting Applications for the Enterprise

This morning I finished reading Dino Esposito's and Andrea Saltarello's book Microsoft .NET: Architecting Applications for the Enterprise. The highest praise for a technical book is that it immediately affected not just the work I was doing, but the way I work. This one did just that.

I've been writing code since I was 8 years old on my school's Commodore PET. That's was almost 30 years ago now. I've been doing it as a career since 1994. I started designing applications (as opposed to just being a code monkey), in 1997. I became what my company calls an Architect last year.

But I didn't start to think like an architect until just recently, and this book, which I power read over the course of 6 days, has had a profound impact on how I see my role within the company, and how I need to work to make myself, and my team more efficient. I've been bringing in tools and processes the last year or so to fix the low hanging fruit, but I still considered myself a developer first, and considered the architect role to be something I did between writing classes and specs.

The first half of this book is about the process. And though the first chapter is a little, um, dry (probably a few too many references to ISO and IEEE), it does help to build the profile for where an architect fits into an organization (big and small). These guys have been there, and done systems development where there is a client involved in the process. They aren't people who have been at some big software company and don't know what is involved in developing line of business software with a client who has no idea what it is they want when the project starts.

The second half of the book talks about application layers: The Business Layer, The Data Access Layer, The Service Layer and The Presentation Layer. I've worked in all these layers at one time or another, but it's only quite recently that I have truly begun to understand the Separation of Concerns rules, and things like dependency injection. This book not only helped top clarify these things in my mind so I can better understand all the other reading that I do that assumes that I know what SoC mean, but it also talked about misconceptions about the layers. I found the section on the service layer particularly appropriate because for a long time, I completely misunderstood Service Oriented Architecture. They cleared this concept up for me in a way no other publication ever has. I wish I had read that 4 years ago. I once built a 'Service Oriented Architecture' application with 80+ web services! What was I thinking?

My favorite part of the book was the 10 Final thoughts, their mantra as they call it. These were spot on, and proved to me that they had been there, and done that, when it came to developing real world applications. It gave them 'geek cred'.

The target audience for this book is probably senior devs and architects. It's probably too high up for low level devs to be interested in (though they should be). I highly recommend it for anyone who is moving up out of the weeds, and anyone who wants a high level picture of some of the most common design patterns in .NET.

The next book I'll be cracking open (tonight on the train ride home), is Julia Lerman's "Programming Entity Framework". 800 pages of data access goodness. Oh My!

Wednesday, February 18, 2009

MS-Test - Not Executed Error

I've finally found out what the issue was with my MS-Test harness, and why I am the only one currently seeing this issue in my office.

First I needed to turn on logging for MS-Test. Here's a link on how to do that.

Then, once I ran my tests, and looked in the log, I saw the following error message:

The Visual Studio performance and coverage logging engine is already running on the computer. Therefore, the test run cannot continue. Close the pending performance or code coverage session and then rerun the tests.

Here's a link to the fix

I'm the only one in the office having this problem, because I am the only one with VS2008 Team System Team Suite and running code coverage and analysis.

I also suspect that I'm the only one who's pounding out all the test code they need to be writing right now, but that's going to change. Soon.

Windows Explorer --- Grrr

Okay, I try not to say anything bad about software that a lot of work has gone into, because, well, I know how hard it is to get it right.

But yesterday I needed to fix a problem on out Team Foundation Server. I needed to get my hands on an executable called TF.EXE. It wasn't (for whatever reason) on my TFS server. Fine, it was supposed to be on my machine (since I have just about every freaking product known to man on my machine it seems). I tried to save myself time by doing a search from my Vista File Explorer (or whatever it is officially called these days). Nothing came back. I hunted around a little bit, searched the web a little bit, and finally just gave up and worked around my problem.

This morning, while fighting another MS-Test - tests not executed issue (if I get one more of these freaking things, I'm going back to NUnit), I stumbled across my C:\Program Files (x86)\Microsoft Visual Studio 9.0\Common7\IDE directory, and lo and behold, there's TF.exe.

So can someone tell me why the hell File Explorer couldn't find it for me yesterday and save me a hour of my time? Why even bother putting the freaking search tool there if it doesn't work? Anyone? Is there a trick to making it search the whole drive? Arrrgggh.

What a great way to start the day!

Monday, February 16, 2009

MSTest - Grrrrrr

I spent two hours plus this mornign trying to find out why my test harnesses all started returning 'Not Executed' when I ran in 'Run Tests in Current Context", but worked fine in "Debug Tests in Current Context". The tests worked on everyone else's computers.

The solution...

I deleted my entire solution folder, and did a get latest from TFS. What a pain in the ass. I was this close to converting back to NUnit.

Design for Reuse?

I've been reading "Microsoft .NET: Architecting Applications for the Enterprise" by Dino Esposito and Andrea Salterello the last few days, and really enjoying it. It's not a detailed coding book, but discusses patterns and approaches, and is bringing me up to speed on some of the areas of development I haven't yet explored, or have explored but need a refresher on. I actually found myself sitting on the couch on Saturday afternoon while the kids were asleep, reading it because it applies directly to what I am doing this week.

One of the points it made (I should have highlighted it, because I can't find the page now), is that you put interfaces on classes not for reusability, but for replacability. That's a whole paradigm change from what I use to do, but have now adopted with TDD and Dependency Injection.

I used to spend hours trying to factor out what I thought would be common code, and got stuck just trying to figure out how loggers would work (in days before log4net) or data access for a certain class. To me, back then, the money was in designing for future needs.

Now I realize that most of those common modules have already been written, and it saves me a lot more time and money to design each class I write with an interface and to be able to swap it out using dependency injection. I can try and guess for years what my next implementation of a business process might look like, and I will fail 99% of the time. Build what you know now, put it behind an interface, and swap out the old for the new.

It seems pretty elementary now, but even a year and a half ago, I didn't get it. It's like a huge weight has been lifted off my shoulders, and I am no longer stuck in future requirements purgatory!

Friday, February 13, 2009

Good Tests Gone Very Bad

I've been writing dozens of tests lately as I have completely bought in to the TDD methodology. I've even turned on code coverage in Team Suite to see just how I'm doing. This may not be a great thing to do if you suffer from OCD, but it sure has helped me to better understand my code. It helps even more when I am walking through other people's code trying to debug something, as I run their tests first, check to see if any lines of code haven't executed as expected, and then write a test to try to execute that code as I would expect. If I still don't get there, I know one of the core assumptions elsewhere is wrong. Its a lot faster than stepping through hundreds of lines of code. It focuses my attention to the problem area much more quickly.

Yesterday morning, I was flying along, writing code, and writing tests, and one of the other developers here came by to ask how to properly test his ViewModel that depended on checking various items on the file system (i.e. does a directory exist, if not, create it).

We're using Rhino Mocks, not TypeMock isolator, so the fact that these System.IO classes are static means that we can't mock them. A little searching revealed that our best option was to create an IFileManager interface with a FileManager class under it, and mock the interface. Not my favorite thing to do, but it works.

I wrote the tests for the new class, and they ran fine.

Then we added that class to my co-worker's class and exposed a property on his interface / class for the IFileManager so that we could pass in a mock.

I ran his tests for his class in debug mode. It worked. Cool.

We wrote some new tests to pass in the mock, and ran those in debug mode. They worked as expected. Awesome!

But here's where things got hairy.

We went to my test list editor, and added them to our global test list, and reran the tests. The failed with a 'Could not load type error'. Hmmm. Must be something wrong with my set up / tear down. So I reran just one of the tests from the test list editor. Still failed. Okay, back to the code. Rerun the test in debug mode. It works. Run the test in 'Run' mode. It fails. WTF?

Check my tests on the FileManager class. They work fine.

Strip the new code out of the ViewModel class. Run the original tests. Pass.

Run the new tests. Fail. Same error. Wait... the class it says it can't load is the class we have completely commented out. Except we left in the using statement. Comment that out. Build. Still failed, same message.

At this point I'm getting pretty PO'd. I force a clean on my whole solution, and rebuild. Tests pass. WTF?

Start adding code back in. Add the using statement. Pass.

Add the reference to the interface. Failed.

Pull the mocking code out of the tests, pass in a real object (not generated by the AutoMockingUnityContainer). Pass. Okay, it's somewhere in the Unity Code. We're now 2 hours into this. I went through this a dozen times, various combinations, until it finally hit me.

The problem wasn't that it couldn't load my FileManager class. By this time, that class had nothing left in it beside a couple of boolean functions that always returned true. What had happened was that immediately before I had been asked to look at this issue, I had installed the October 2008 release of the Enterprise Application Library (Version 4.1) to make use of the Validation Application Block. I had previously just installed the Unity Framework separately. I now had two versions of the Unity Framework installed on my machine, with the same version numbers, but from different locations on my machine.

I uninstalled the Enterprise Library, restarted my IDE, and ran my tests successfully. I readded all the code I had commented out, and the tests ran as expected. I think we spent three hours on this one yesterday (x2 since two of us were trying to figure it out)

Now I have to decide when to have the team install the app blocks on thier machines, and to remind them to unistall Unity and any old versions first.

Random VS2008 Crashes

For the past few weeks, I've been having a lot of problems with VS2008 crashing randomly on my PC. I've been installing a lot of tools and components lately, so I have little doubt that something I've installed recently was causing it to BSOD (Black Screen of Death in this case).

This morning, I was trying to add the Microsoft.IdentityModel.dll to my tool box, and it kept crashing. I finally had enough, and decided to Google for a solution. The link below fixed the problem on the first try. Yes!

Sometimes it pays to spend 2 minutes fixing the problem instead of just ignoring it and hoping it will go away.

Wednesday, February 4, 2009

AutoMockingUnityContainer and Rhino Mock

I've been putting a lot of time into understanding TDD and Mocking the last few weeks. Combine that with Unity, and it's a lot of stuff to get a grip on.

I've been going with Rhino Mock as my mocking framework, and it seems to work okay as long as you are developing new code. If I were working on legacy code, I think it's pretty clear you would want to use TypeMock Isolator. You could justify the expense pretty quickly.

I was trying to use Roy Osherove's AutoMockingUnityContainer to make my test fixtures perfect, since I am setting up the model for all the other devs to follow. Roy published this back in April 2008, and since then, Rhino Mock has released a new version that makes use of lambda expressions to eliminate the need to do the mocks.Record step. Instead, you should be able to do the following:

ILogger logger = container.Resolve();
logger.Stub(x => x.IsLogFileFull()).Returns(true);

I say should, because this is what I understand. I may have misunderstood.

This should force the IsLogFileFull to always return true when called in the example Roy shows. But for some reason, it always returns false for me. I went through a hundred iterations of code, and ended up going back to the original syntax, which isn't quite as clear, but works.

I will say that my "Logger" class is not passed into the constructor but is set as a property after the class is resolved. Maybe that is the issue, but I am testing a very high level function, and it calls a number of different classes that I want to mock / stub, and I would hate to have a class that has five or six arguments required in the constructor (even if it is just for testing sake). The class is wired up to Unity itself so I normally don't need to pass these in, just when I want to mock.

Maybe that is a reason in itself to go to TypeMock, but I need to prove to my folks here that TDD and Mocking is going to pay off at all, before I try to prove that we need to spend more money to do it.