in reply to Testing procedure: how to mock?

thor

I think the first question you should ask yourself is whether you need to be testing your database code. Meaning the code which utilizes DBI, and which generates SQL statements.

If the answer is yes, I would suggest using DBD::Mock. It will allow you to mock your DBI/database interaction, and interogate the SQL being passed into it. I wrote an article on perl.com about it a little while ago, which explains the basics of using the module.

If your answer is no, and you are not concerned with testing the SQL or DBI code, and your are not finding Test::MockObject or Test::MockModule useful, you might want to also look at Sub::Override or possibly Test::MockDBI.

In addition, you could post some of your Test::MockObject or Test::MockModule code, and possibly someone could help you with getting it to work.

-stvn

Replies are listed 'Best First'.
Re^2: Testing procedure: how to mock?
by thor (Priest) on Sep 26, 2005 at 20:43 UTC
    In addition, you could post some of your Test::MockObject or Test::MockModule code, and possibly someone could help you with getting it to work.
    Ask, and ye shall receive. :)
    ============== Foo.pm ============== package Foo; use strict; require Exporter; our @ISA = qw(Exporter); our %EXPORT_TAGS = ( 'all' => [ qw( foo ) ] ); our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); our $VERSION = '0.01'; sub foo { die "This is being called from Foo\n"; } 1; __END__ ============== Bar.pm ============== package Bar; use strict; use Foo qw(foo); our $VERSION = '0.01'; sub new { my ($class) = @_; my $self = []; bless($self, $class); } sub bar { my ($self) = shift; foo(); } 1; __END__ ============== Baz.pl ============== use strict; use warnings; use Test::MockModule; use Bar; { my $mock = Test::MockModule->new('Foo'); $mock->mock('foo', sub {print "Successfully mocked!\n";}); my $bar = Bar->new(); $bar->bar(); }
    Thanks in advance,

    thor

    Feel the white light, the light within
    Be your own disciple, fan the sparks of will
    For all of us waiting, your kingdom will come

      thor

      Your problem here is that your Foo module has already exported &foo into Bar's namespace by the time you have mocked anything. What you want to do is to mock Foo before loading Bar, like this:

      use strict; use warnings; use Test::MockModule; my $mock = Test::MockModule->new('Foo'); $mock->mock('foo', sub {print "Successfully mocked!\n";}); require Bar; my $bar = Bar->new(); $bar->bar();
      Personally I don't think this is ideal since you need to require Bar rather than use it.

      However, since you are exporting &Foo::foo into Bar, you could ignore the fact &Foo::foo came from Foo, and just mock &foo inside Bar. Like this:

      use strict; use warnings; use Test::MockModule; use Bar; my $mock = Test::MockModule->new('Bar'); $mock->mock('foo', sub {print "Successfully mocked!\n";}); my $bar = Bar->new(); $bar->bar();
      This too is probably not ideal.

      Of course, if you simply do not export &Foo::foo, and instead call with the fully qualitied packag name (Foo::foo()) then you original test code will work.

      -stvn