Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"
 
PerlMonks  

Trapping exit AND using mocked objects?

by LANTI (Sexton)
on May 07, 2010 at 08:25 UTC ( #838888=perlquestion: print w/replies, xml ) Need Help??
LANTI has asked for the wisdom of the Perl Monks concerning the following question:

Hi, I am writing a script for checking a filer. In order to test the script, I need predictable results and therefore use Test::MockObject to mock the answers from the server inside of the test-script. To have this mocked module being used by the tested script, I eval the tested-script, after reading it in by use of File::Slurp.

Bellow some code, the tested script is wrapped in a sub for simplicity.

#!/usr/bin/perl -w use warnings; use strict; use feature qw(switch say); use Test::More 'no_plan'; use Test::Trap; use Test::MockObject; my @r = trap { some_code() }; my $mock = Test::MockObject->new(); $mock->fake_module ('NaServer', new => sub { return 'NaServer' }, set_style => sub ($) {return 'ok'}, set_admin_user => sub ($$) {return 'ok'}, set_timeout => sub ($$) {return 'ok'}, ); use_ok( 'NaServer' ) or exit; my $ob = NaServer->new(); isa_ok ($ob, 'NaServer'); sub some_code { say 'hello world'; #use_ok( 'NaServer' ) or exit; ## commented out by intend!! my $o = NaServer->new(); exit 111; } is ( $trap->exit, 111, 'Exit ist 111');

Any idea how I can trap the exit 111 and still have the code executed in the lexical context of the test-script (or get the mocked NaServer instead of the one, used by the tested-script)?

Just to make things clear: The real script I want to test, has the use NaServer line not commented out, but since the NaServer Module is already loaded in the test-situation its not used again.

Cheers, Ingo

Replies are listed 'Best First'.
Re: Trapping exit AND using mocked objects?
by moritz (Cardinal) on May 07, 2010 at 09:42 UTC
    sub some_code { say 'hello world'; #use_ok( 'NaServer' ) or exit; ## commented out by intend!! my $o = NaServer->new(); exit 111; }

    I don't understand why you call exit in your test script - is there a particular reason? (Update: from CB discussion I've learned that some_code is actually part of the tested script, though I don't understand why it then contains use_ok...)

    Also what stops you from first setting up the mock object, and then calling trap()?

      Your comments both in the CB and here helped to find the solution. Following the code which should clearly demonstrate both the the problem and the solution. Thanks for your help!

      script_to_test.pl

      #!/usr/bin/perl -w use warnings; use strict; use feature qw(switch say); use NaServer; my $session = NaServer->new(); my $val = $session->get_val(); if ($val > 500 ) { say 'Value to high: ' . $val; exit 2; } else { say "Value OK ($val)"; exit 0; }

      NaServer.pm - Dummy Module

      package NaServer; # this is just a dummy version of NetApps NaServer !! use strict; use warnings; use Carp; sub new { my $class = shift; my $self = {}; bless \$self, $class; } sub get_val { return rand 1000; } 1;

      eval.t (this did not work)

      #!/usr/bin/perl -w use warnings; use strict; use feature qw(switch say); use Test::More tests => 3; use Test::MockObject; use Test::Output; my $mock = Test::MockObject->new(); $mock->fake_module ('NaServer', new => sub { return 'NaServer' }, get_val => sub { return 500 }, ); use_ok( 'NaServer' ) or exit; ## includes 'use NaServer;' # Construction of $s just for testing my $s = NaServer->new( 'sim8aXXXXXX', 1, 6 ); isa_ok( $s, 'NaServer'); # ================================== # = Tests of the script start here = # ================================== use File::Slurp; my $script = 'script_to_test.pl'; eval 'package Script; sub test {' . read_file($script) . '}'; stdout_is { Script::test() } qq{Value OK (500)\n}, 'stdout as expect +ed'; __END__ ## This does not work as expected, since the test stdout_is is never r +eached. ## Exits in script_to_test.pl prevent this.

      trap.t (this one works)

      #!/usr/bin/perl -w use warnings; use strict; use feature qw(switch say); use Test::More tests => 3; use Test::MockObject; my $mock = Test::MockObject->new(); $mock->fake_module ('NaServer', new => sub { return 'NaServer' }, get_val => sub { return 500 }, ); use_ok( 'NaServer' ) or exit; ## includes 'use NaServer;' # Construction of $s just for testing my $s = NaServer->new( 'sim8aXXXXXX', 1, 6 ); isa_ok( $s, 'NaServer'); # ================================== # = Tests of the script start here = # ================================== use Test::Trap; use File::Slurp; my $script = 'script_to_test.pl'; my @r = trap { eval read_file($script) }; is ($trap->stdout, "Value OK (500)\n", 'stdout as expected'); __END__ # This works fine, traping after having mocked the NaServer was the tr +ick. # Thanks to the monks!

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://838888]
Approved by Hue-Bond
help
Chatterbox?
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others taking refuge in the Monastery: (3)
As of 2018-04-24 04:00 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    Notices?