代码之家  ›  专栏  ›  技术社区  ›  Colin Fine

如何防止Perl出于测试目的使用模块?

  •  5
  • Colin Fine  · 技术社区  · 14 年前

    我正在开发一套Perl脚本和模块,然后在我们公司的不同机器和系统上进行部署。 有些设备依赖于一个特定的模块,该模块可能安装在不同的机器上,也可能不安装在不同的机器上。我使用“eval”来检测此模块是否可用。

    我刚刚收到了一个故障报告,结果是用户没有成功地在他的机器上安装模块(但没有意识到他没有这样做):但我的代码中的错误是,在这种情况下,我没有将错误条件传递到最高层,所以它丢失了,而脚本只是默默地没有执行部分它的功能。

    为了调查它,我禁用了我机器上的特定模块,并且很容易找到并解决了问题。但是我唯一能想到的禁用它的方法,除了卸载它,就是重命名文件(当然,我必须通过sudo来完成)。

    我现在运行的所有测试都无法使用这个模块,并且在其他一些地方我没有正确处理这种情况。

    但是我现在要做的是为这种情况编写一些测试:但是我如何在自动测试中明智地使这个模块暂时不可用。我真的不希望我的测试使用sudo将模块移动到其他地方(我可能同时在机器上做其他事情)。

    是否有人知道我可以告诉Perl“不要在我试图‘使用’或‘要求’的任何地方发现这个模块,用于测试目的”?

    我正在运行Perl5.10.0(在Fedora12上),并使用test::more和tap::harness。我们的一些安装运行的是Perl5.8,所以我愿意在测试中使用5.10特性,而不是代码本身。

    2 回复  |  直到 14 年前
        1
  •  11
  •   rafl    14 年前

    Test::Without::Module Devel::Hide @INC CORE::GLOBAL::require perldoc -f require

        2
  •  4
  •   DVK    14 年前

    1. Test::Without::Module

    2. @INC use require require's perldoc

    # The following code was not tested - for illustrative purposes only
    # MUST be done in the BEGIN block at the very beginning of the test
    # BEFORE any "use Module"; lines
    push @INC, \&my_sub; 
    my %prohibited_module_files = map { $_=> 1} ("Foo/Bar.pm", "x.pm");
                                  # Ideally, translate module names into file names
    sub empty_module_sub {
        $_ = "1;\n"; # Empty module
        return 0; # End of file
    }
    sub my_sub {
        my ($coderef, $filename) = @_; # $coderef is \&my_sub
        if ($prohibited_modules{$filename}) {
            print STDERR "NOT loading module $filename - prohibited!\n";
            # Optionally, die here to simulate not finding the module!!!
            # Otherwise, load empty package
            return (undef, \&empty_module_sub);
        }
        return undef; # Continue searching @INC for good modules.
    }
    

    $INC{$filename} undef 1 %INC BEGIN