A: 

Does your mocking manipulate the symbol table? I've seen a bug in the debugger that interferes with symbol table munging. Although in my case the problem was reversed; the code broke under the debugger but worked when run normally.

Michael Carman
No, my mocked routine just returns an undef so that my error handling code will run. I added a working example to my question so hopefully some smart Perl guru will be able to witness my problem first hand and tell me how to fix it.
Kurt W. Leucht
Actually, Test::MockModule does manipulate the symbol table. I've added another answer that addresses the revised question, but am leaving this one for reference.
Michael Carman
+1  A: 

Both Exporter and Test::MockModule work by manipulating the symbol table. Things that do that don't always play nicely together. In this case, Test::MockModule is installing the mocked version of slurpFile into UtilityModule after Exporter has already exported it to MainModule. The alias that MainModule is using still points to the original version.

To fix it, change MainModule to use the fully qualified subroutine name:

 my $file_contents = UtilityModule::slurpFile($file_name);

The reason this works in the debugger is that the debugger also uses symbol table manipulation to install hooks. Those hooks must be getting installed in the right way and at the right time to avoid the mismatch that occurs normally.

It's arguable that it's a bug (in the debugger) any time the code behaves differently there than it does when run outside the debugger, but when you have three modules all mucking with the symbol table it's not surprising that things might behave oddly.

Michael Carman
Perfect! Thanks! Now my statement coverage is well within the acceptable range!
Kurt W. Leucht