我如何模拟Log :: Log4perl :: INFO?

时间:2011-06-23 14:34:02

标签: perl unit-testing mocking log4perl

我正在为使用Log::Log4perl的现有模块编写新的单元测试,如:

use Log::Log4perl qw(:easy);

模块调用INFO( "important message" );。我想模仿这个来验证我的测试代码在某些情况下调用了INFO

当我运行测试模块时,它不会从模块中捕获对INFO的调用。模拟这些INFO调用的正确方法是什么?

这是一个完整的例子:

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...
}

2 个答案:

答案 0 :(得分:2)

我查看了Log4perl.pm在:easy情况下正在做什么,它修改了调用模块的命名空间以添加记录器和INFO功能(等等)。

所以我要覆盖的函数实际上是在Mut.pm中。这个重写的测试模块做了我想要的。

#!/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' );
}

答案 1 :(得分:1)

CPAN上有一个Test::Log::Log4perl模块,允许您发送预期记录在一段代码中的消息,并将其与实际记录的内容进行比较。