将分层Perl模块导入本地名称空间

时间:2010-01-29 01:14:20

标签: perl unit-testing

情况:

我有一个模块Foo::Quux::Bar,住在./Bar.pm。我需要能够单独测试Bar。但是,由于我无法控制的情况来设置Foo / Quux目录结构,这是不利的。

所以我想做的是有一些unit_test_use例程让我抓住Bar.pm并将其函数移动/复制到本地命名空间(注意Bar有一个package Foo::Quux::Bar说明符)测试乐趣。

在Perl文档中喋喋不休并没有帮助我。

3 个答案:

答案 0 :(得分:5)

假设您的Bar.pm以标准方式导出其功能,您可以使用require加载它并手动导入:

BEGIN { 
    require 'Bar.pm';        # now the package Foo::Quux::Bar is set up
    Foo::Quux::Bar->import;
};

但是如果可以的话,绝对值得研究以标准方式设置目录结构。

答案 1 :(得分:4)

以下示例使用以下Bar.pm

package Foo::Quux::Bar;

use warnings;
use strict;

sub one { 1 }

sub two { "zwei" }

sub three { 0x3333 }

1;

test-bar程序中,您可以安装一个钩子,该钩子将使用当前目录的Bar.pm

#! /usr/bin/perl

use warnings;
use strict;

use File::Basename;

BEGIN {
  sub find_bar {
    my(undef,$name) = @_;

    if (basename($name) eq "Bar.pm") {
      open my $fh, "<", "./Bar.pm" or die "$0: open ./Bar.pm: $!";
      $fh;
    }
  }

  unshift @INC => \&find_bar;
}

@INC中记录了import中的挂钩。

现在导入所有潜艇,忽略Foo::Quux::Bar中的任何# fake use Foo::Quux::Bar BEGIN { require Foo::Quux::Bar; { no strict 'refs'; while (my($name,$glob) = each %Foo::Quux::Bar::) { if (*{ $glob }{CODE}) { *{ __PACKAGE__ . "::" . $name } = *{ $glob }{CODE}; } } } }

strict

在启用了print map "$_\n", one, two, three; 编译指示的测试代码中退出,我们可以

{{1}}

并获得以下输出:

1
zwei
13107

答案 2 :(得分:0)

这是我写的:

sub import_module_into_main
{
   my ($mod_name, $filename) = @_;

   require $filename;

   no strict;
   foreach my $var ( keys( %{$mod_name . "::"}))
   {
      $main::{$var} = ${$mod_name. "::"}{$var};
   }

}

使用以下方式调用:import_module_into_main("Foo::Quux::Bar", "Bar.pm")