Lanx: I have problems to see a case where my approach doesn't work.
I have been referring to your initial sentence (emphasis added):
LanX: After useing test_v1.pm you have to make Perl believe that package Foo and package Foo::Bar have already been loaded ...
Your approach works in most cases, but you don't have to modify %INC in the cases I've shown.
Can I whip up an example where it actually breaks? Probably. I've done some security testing in my career, and to do that you often need to find an economic way to simulate an error situation which "does not happen normally" and check how an application behaves. It isn't really short, but hopefully self-contained and correct enough.
Let's consider this application App.pm which needs some critical resource, which in our example is the Perlmonks website:
# App.pm
package App;
use Foo;
sub new {
my $class = shift;
bless { ua => Foo->new }, $class;
}
sub check {
my $self = shift;
my $res = $self->{ua}->get('https://perlmonks.org');
if ($res->code != 200) {
return "Monks are offline";
}
return "Everything works just fine";
}
1;
The Foo module is pretty short.
# Foo.pm
package Foo;
use parent 'LWP::UserAgent';
1;
Now how do we get test coverage in the branch where it deals with "Monks are offline"? I can't shut down the Perlmonks server, and let's for the moment assume that I can't just manipulate the network, because other parts of the application need their connections. But I can make sure that Foo will behave as if Perlmonks were down. I'll do this with a test class test_v1:
# test_v1.pm
package Foo;
use HTTP::Response;
sub get { return HTTP::Response->new(500); }
# Add more packages ad libidum
1;
A testfile would look like this:
# errorcode.t
use test_v1;
# %INC modification, as prescribed by LanX
#BEGIN {
# $INC{'Foo.pm'} = __FILE__;
#}
use Test::More;
use App;
my $app = App->new;
is($app->check,"Monks are offline");
done_testing;
If you comment out the behaviour modification, then the test will fail (unless Perlmonks are really down). If you uncomment the %INC modification, then the test will fail with Can't locate object method "new" via package "Foo" at App.pm line 7.
I usually avoid such a construct and instead explicitly use Foo; before doing any behaviour modification. In that case, the %INC modification would be harmless, but still useless and by no means required.
Cheers, haj
P.S.: Good that I'm typing so slow. You're editing your posts so often that I have to occasionally check what I'm actually responding to.
|