Nerdy tidbits from my life as a software engineer

Monday, March 2, 2009

Mock State Visualizer To The Rescue

I spent some time a few months ago working on an implementation for a mock state visualizer.  Basically, I now have the ability to save an html file to the output directory where the unit test results are stored that lets you visualize the expected calls and the actual calls.  Today, as I was wracking my brain trying to figure out why my expectations weren’t being fulfilled, I made use of this awesome feature for the first time.  Here’s what I found:


What you’re seeing here is the recorded state machine on the left, and the attempt to replay it on the right.  Each state on the left has a number of links between itself and the next state (and in all cases itself so that it can support ranged expectations, such as setting an expectation that set_LogFilePath is called between 3 and 6 times).  Each bullet on the left represents a method expectation between that state and another one.  The red lines on the replay log column are the links between states that fail to validate.  Since none of these calls repeat, there is a failing validation for each of these – but that’s OK because there are links in states 0 through 4 that can be validated.  This means that the mock framework found a way to validate the current method in each of these cases and walk from one state to the next.  This is how the validation process works.

The problem can be found in state 5.  Here, none of the links in state 5 could be validated.  This means that there is a mismatch between the expectations set in the unit test and the actual methods called in the target method.  You can see from the log that the problem is that my unit test was setting an expectation to have set_IsReplaying called, but get_IsReplaying was called instead.  Actually, in this case, the unit test is the problem, not the target code.

But wow, is a picture is worth 100,000 words.  Where as before I was having trouble figuring out which call was bad and where that call was coming from, a quick look at the chart above solves that problem.  Now that I know which call is failing and where it is, I can go fix my test and move on.

Implementing that replay log was time well spent.