Intro

Warning: if you have never wrote automated tests for your code,
if you have no idea what about it and if you do not know why you want
to write them then please read first An
Introduction to Testing.

It is easy to write tests for code which doesn't have dependancies on
external environment. When you write tests, say, for implementation of
some mathematical algorithm you have easily controlled
environment. Everything you have to worry about is supplying input
values and comparing them with output. But how can you test code
which, say, sends emails using Net::SMTP module? To satisfy
requirement for controlled environment you will have to run test mail
server which must be controlled by test code.

Often very simple technique of using fake intefaces may be much more
easier alternative. Instead of running test mail server emulate
Net::SMTP interface in test code. Emulation may actually do
not send emails over network but pass information about sent emails
to testing code.

I'll try to show this technique on example of Perl module which uses
Apache API (so it expects mod_perl environment) and I'll show how it
can be tested using emulated mod_perl environment.

Test Script

As POD documentation says this module relies on mod_perl API. So how
are we going to write tests for it without using Apache configured
with mod_perl support?

It is much more easier to fake mod_perl environement instead of using
Apache for automated tests. There is no need to emulate all mod_perl
API. It is sufficient to emulate only parts of it which are used in
the module.
Apache emulation interface can be implemented using fake Apache
module. I.e:

In that example, you're creating a module "Baz", and you want to use Test::MockObject to dummy up a Foo::Bar object. What do you do, though, if $things is not a valid argument to Foo::Bar? There's a good chance that your mock object won't catch this (I've been bitten by this).

Of course, this testing module isn't designed to catch things like that because it's not supposed to. In fact, you could leave the use statement and the constructor out of there and if the rest of the module depends on that object, the mock object may very well still allow the module to work.

Once you have the basic functioning of your code working with this module, then you need to run integration tests without it. Test::MockObject can actually obscure many integration bugs if you're not careful. However, since this module was specifically designed for unit testing, that's not to be taken as criticism. All in all, I give it two thumbs up.