2

I'm writing new unit tests for an existing module that uses Log::Log4perl like:

use Log::Log4perl qw(:easy);

The module calls INFO( "important message" );. I'd like to mock this to verify from my test code that INFO is called in certain circumstances.

When I run the test module it doesn't capture the calls to INFO from the module. What's the right way to mock these calls to INFO?

Here's a complete example:

Mut.pm

#!/usr/bin/perl -w
# Mut : Module under test

use strict;
use warnings;

package Mut;

use Log::Log4perl qw(:easy);

sub new {
   my $class = shift;
   my $self = {};
   bless $self, $class;

   INFO( "Mut::new" );

   return $self;
}

1;

Mut.t

#!/usr/bin/perl -w

use strict;
use warnings;

package Mut_Test;

use Test::More tests => 1;
use Test::MockModule;
use Test::MockObject;

my @mock_info_output = ();

my $log4perl = Test::MockModule->new('Log::Log4perl');
$log4perl->mock(
   'INFO' => sub {
      print STDERR $_[0];
      push @mock_info_output, @_;
      return;
   }
    );

BEGIN {
  use_ok('Mut');
}

{
   my $mut = Mut->new;
   ## Do something here to verify INFO...
}
bstpierre
  • 30,042
  • 15
  • 70
  • 103

2 Answers2

3

I looked at what Log4perl.pm is doing in the :easy case, and it modifies the calling module's namespace to add a logger and INFO function (among others).

So the function I want to override is really in Mut.pm. This rewritten test module does what I want.

#!/usr/bin/perl -w

use strict;
use warnings;

package Mut_Test;

use Test::More tests => 2;
use Test::MockModule;
use Test::MockObject;

my @mock_info_output = ();

my $mock;

BEGIN {
  use_ok('Mut');

}

$mock = Test::MockModule->new('Mut');
$mock->mock(
   'INFO' => sub {
      print STDERR "INFO: $_[0]\n";
      push @mock_info_output, @_;
      return;
   }
    );

{
   my $mut = Mut->new;
   is( @mock_info_output, 1, 'just one line' );
}
bstpierre
  • 30,042
  • 15
  • 70
  • 103
1

There's a Test::Log::Log4perl module on CPAN that allows you to send the messages you expect to be logged in a snippet of code and compare it against what was actually logged.