0

First of all, I think somebody needs to rewrite my question, I know what I am asking, not how I should ask it precisely.

Assume I have some local module LOCAL::Commons and it has one subroutine called globalTrim. I am testing that subroutine below, and while LOCAL::Commons is installed under /usr/local/lib/perl, the module I am testing below is located in directory /home/me/perl/LOCAL/. See how I am using use lib ... to make sure I am not using LOCAL::Commons located in /usr/local/lib/perl (I have this directory on my path).

Now, if LOCAL::Commons is using another local module LOCAL::Cool (that is, not from cpan), and I have also made some changes to that module, how can I make sure my tests are using the correct modules? That is, I want LOCAL::Commons to use /home/me/perl/LOCAL/Cool and not /usr/local/lib/perl/LOCAL/Cool.

#!/usr/bin/perl 
# test_local_commons.pl
# directory: /home/me/perl

use strict;
use warnings;
use Test::More 'no_plan';
use File::Temp qw( tempfile tempdir );

use Cwd qw();
use lib  Cwd::abs_path();
# Testing 
use LOCAL::Commons qw ( globalTrim );

sub newTest($) {
    my $name = shift;
    print "---------------------------------------------------\n";
    print $name, "\n";
    print "---------------------------------------------------\n";
}

sub testTraverse {
   is(globalTrim("  - stackoverflow  - ), "-stackoverflow-", "Passed" );
}

newTest "testTraverse"; testTraverse ();
Sinan Ünür
  • 116,958
  • 15
  • 196
  • 339
Gogi
  • 1,695
  • 4
  • 23
  • 36

5 Answers5

3

If you run this like so:

perl -I/home/me/perl test_local_commons.pl

It should ensure your /home/me/perl version is checked first

Moritz Bunkus
  • 11,592
  • 3
  • 37
  • 49
Lucas
  • 14,227
  • 9
  • 74
  • 124
  • But this may silently pick up a module of the same name later in @INC. – C. Ramseyer Mar 20 '13 at 15:33
  • @C.Ramseyer, true, but the question implies that the `LOCAL::Cool` package will be available in `/home/me/perl`, so I didn't go there. Good point anyway. – Lucas Mar 20 '13 at 15:35
2

After you load the files you want, put this:

die 'Included PRODUCTION Module!!!' 
    if grep { m{/usr/local/lib/perl/LOCAL/Cool} } values %INC
    ;

Of course you could die for any module you wanted.

For example, we've got this tool at work that works with Activestate's PerlEZ.dll. We don't want to deploy it with Perl installed. But we need to use some libraries, which we hide elsewhere. When I'm testing my code I include a module from our hidden path. It blows up anytime it sees a standard library path in %INC. We want to make sure it almost everything from the @INC hook and the special libraries.

Axeman
  • 29,660
  • 2
  • 47
  • 102
2

I suggest using Perlbrew to make a completely separate Perl installation for testing. That way you control the testing environment and don't really have to worry about it.

1

You could just add a BEGIN{ @INC = qw(directories you want to allow)} block. While using PERL5LIB, use lib etc. just appends to the include path, this will completely replace it, thus eliminating the danger that the module is picked up later in the search path, e.g. because you forgot to install it /home/me/perl/.

But the real TDD answer is probably to use mock modules for everything that's not the module under test.

C. Ramseyer
  • 2,322
  • 2
  • 18
  • 22
1

use lib has process scope -- that is, it changes the value @main::INC with global visibility, just as a non-localized assignment to @INC would. That means that any modules that you load after saying use lib will check the include path you've set.

As to what path use lib sets, it explicitly adds to the front of @INC so that later calls to use lib will be considered earlier when searching for modules.

The upshot of which is that it looks to me like your code sample will just work. Note that I'm going to discourage you from checking that you're using the under-development version in your test. That would cause your test to fail based on something unrelated to whether the function under test actually works correctly. (But note also that you should also have written unit tests for LOCAL::Cool.)

darch
  • 4,200
  • 1
  • 20
  • 23