sid_com
sid_com

Reputation: 25117

How to check the availability of a module that requires an explicit import in a test?

I've seen this in test examples:

eval "use Test::Module";
plan skip_all => "Test::Module required to test ..." if $@;

But when I try this with a module which requires to explicitly import a function I get an error.

eval "use Test::Module qw( function )";
plan skip_all => "Test::Module required to test ..." if $@;

Can't locate object method "function" via package "1" (perhaps you forgot to load "1"?)

How could I prevent this error?

If I load the module without eval it works fine.


Example:

use warnings;
use strict;
use Test::More;

eval "use Test::Warnings qw( :all )";
plan skip_all => "Test::Warnings required" if $@;

like( warning { warn "Hello" }, qr/Hello/, "Test for 'Hello' warning" );

done_testing();

Output:

PERL_DL_NONLAZY=1 /usr/local/bin/perl "-MExtUtils::Command::MM" "-MTest::Harness" "-e" "undef *Test::Harness::Switches; test_harness(0, 'blib/lib', 'blib/arch')" t/*.t
t/warn.t .. Hello at t/warn.t line 8.
Can't locate object method "warning" via package "1" (perhaps you forgot to load "1"?) at  t/warn.t line 8.
t/warn.t .. Dubious, test returned 255 (wstat 65280, 0xff00)
No subtests run 

Test Summary Report
-------------------
t/warn.t (Wstat: 65280 Tests: 0 Failed: 0)
  Non-zero exit status: 255
  Parse errors: No plan found in TAP output
Files=1, Tests=0,  0 wallclock secs ( 0.01 usr +  0.00 sys =  0.01 CPU)
Result: FAIL
Failed 1/1 test programs. 0/0 subtests failed.
make: *** [test_dynamic] Fehler 255

Upvotes: 2

Views: 199

Answers (3)

tobyink
tobyink

Reputation: 13664

Try forcing the import to happen at compile-time:

BEGIN {
  eval "use Test::Module qw( function ); 1"
    or plan skip_all => "Test::Module required: $@";
};

Also, take a look at Test::Requires, which makes doing this sort of thing much easier.

Upvotes: 1

Miller
Miller

Reputation: 35198

Your code has nothing to do with the error:

eval "use Test::Module qw( function )";
plan skip_all => "Test::Module required to test ..." if $@;

The above can't throw an error since the eval is trapping it, and it's printing out completely different text.

The following WOULD throw the error:

my $aa = 1;
$aa->function('foobar');

Therefore, either just follow the line number that the error reported, or just look for places where you're using function on a variable you mistakenly are treating like an object.

Upvotes: 0

Kizzim
Kizzim

Reputation: 112

eval {
    require My::Module;
    My::Module->import( function );
}

Upvotes: 0

Related Questions