On Thu, Dec 12, 2002 at 03:27:32PM -0600, Danny Faught wrote:
> I have a legacy Perl script, not object-oriented but at least ported to 
> Perl 5.  I want to use a real-world example, rather than new code like 
> what Kent Beck uses in the book Test-Driven Development.  So I thought 
> I'd implement a unit test for one of the functions in this old script. 
> I'm using Test::Unit::Procedural.
> 
> I'm pulling my hair out trying to stub out the functions that the 
> function under test is calling.  Here's the function (complete with an 
> error that will be corrected as part of the exercise):
> 
> sub abort_handler {
>     my ($event) = @_;
>     print STDERR "stress_driver: aborted by SIG$event->data()\n";
>     &log ("stress_driver: aborted by SIG$event->data()");
>     exit (&cleanup);
> }
> 
> I want to stub out (replace) the &log and &cleanup functions and the 
> builtin exit function.

In your test, do something like this:

BEGIN {
    # Override with itself so it can be overridden at run-time later.
    *CORE::GLOBAL::exit = sub {
        CORE::exit @_;
    }
}

{
     my $exit_code;
     no warnings 'redefine';
     local *CORE::GLOBAL::exit = sub {
         $exit_code = shift;
         goto EXIT;
     };
     
     my @logs = ();     
     local *Foo::log = sub {
         push @logs, @_;
     }
     
     my $cleanup_called = 0;
     local *Foo::cleanup = sub {
         $cleanup_called++
         return something;
     }
     
     ...do code which calls abort handler...
     EXIT: ..tests here...

}


> I'll probably also want to redirect STDERR to capture that output as well

That's easy, tie it.  Look at t/lib/TieOut.pm in the Test-Simple tarball.


>  But I can't figure out how to turn unit test mode on and off.

Scripts are hard to test.  Libraries are easy.  So...

Step 1:  pull all the subroutines out of the script and into a seperate
library.

Step 2:  test that library.

That leaves a lot less to try and test in the script.

Beyond that the real problem is that scripts must be called as seperate
processes which makes much of the subroutine overriding tricks above
difficult.  I have a trick which simulates running a perl script, but all
its really doing is eval'ing the code in the current process.  This means
the tricks above will work.

It can be found here: 
http://www.pobox.com/~schwern/tmp/esmith-TestUtils.pm

Adapt as you like.


-- 

Michael G. Schwern   <[EMAIL PROTECTED]>    http://www.pobox.com/~schwern/
Perl Quality Assurance      <[EMAIL PROTECTED]>         Kwalitee Is Job One
conway: unit of mind expansion.  One Conway == ~20 lines of Perl code
  found in $CPAN/authors/id/D/DC/DCONWAY, which gives the sensation
  of your brain being wrapped around a brick, with kiwi juice squeezed
  on top.
        -- Ziggy

Reply via email to