How to redefine a sub during testing?

K

kj

During testing it'd often be *very handy* to be able to redefine
a function/subroutine. (E.g., subroutine Foo::A gets a particular
value from subroutine Foo::B, which in turn performs some elaborate
websearch to get this value; it would simplify the testing of Foo::A
tremendously to be able to replace Foo::B with a simple sub that
returns a hard-coded value, thus decoupling the testing of Foo::A
from the testing of Foo::B.)

When subclassing is an option, that's usually the way to go, but
now I'm dealing with packages that are not using the OO calling
model, so this is not an option.

I'm thinking that there must be some "symbol table surgery" that
I may be able to perform to temporarily replace the original sub
with another one, but I'm a bit shaky on symbol table manipulations.

Be that as it may, any advice on how to redefine the likes of Foo::B
during testing would be much appreciated.

Thanks!

kj
 
K

kj

Please disregard the blather below... (I had forgotten a "use
warnings FATAL => 'all'" in my code...)

kj






During testing it'd often be *very handy* to be able to redefine
a function/subroutine. (E.g., subroutine Foo::A gets a particular
value from subroutine Foo::B, which in turn performs some elaborate
websearch to get this value; it would simplify the testing of Foo::A
tremendously to be able to replace Foo::B with a simple sub that
returns a hard-coded value, thus decoupling the testing of Foo::A
from the testing of Foo::B.)
When subclassing is an option, that's usually the way to go, but
now I'm dealing with packages that are not using the OO calling
model, so this is not an option.
 
A

anno4000

[...]
When subclassing is an option, that's usually the way to go, but
now I'm dealing with packages that are not using the OO calling
model, so this is not an option.

I'm thinking that there must be some "symbol table surgery" that
I may be able to perform to temporarily replace the original sub
with another one, but I'm a bit shaky on symbol table manipulations.

While you have withdrawn your question in a followup, it is still
valid. The symbol table surgery is rather simple. You can redefine
(at runtime) functions in a module you have loaded. The module
will then use your redefined version(s) internally.

Here is a demonstration using Data::Dumper. Internally, the function
Dumper() is defined as

sub Dumper {
return Data::Dumper->Dump([@_]);
}

So redefining Data::Dumper::Dump will change the behavior of the
imported function Dumper() (and make Data::Dumper useless), as
shown below:

use Data::Dumper;

my @l = qw( one two three);
print Dumper( \ @l);

*Data::Dumper::Dump = sub { "hihi haha hoho\n" };
print Dumper( \ @l);

That prints

$VAR1 = [
'one',
'two',
'three'
];
Subroutine Data::Dumper::Dump redefined at ./ttt line 12.
hihi haha hoho


That's as close as you get to subclassing an exporting module.
The technique may be okay for speeding up tests, but never in
production code.

Anno
 
P

Peter Scott

During testing it'd often be *very handy* to be able to redefine
a function/subroutine. (E.g., subroutine Foo::A gets a particular
value from subroutine Foo::B, which in turn performs some elaborate
websearch to get this value; it would simplify the testing of Foo::A
tremendously to be able to replace Foo::B with a simple sub that
returns a hard-coded value, thus decoupling the testing of Foo::A
from the testing of Foo::B.)

See Test::MockModule. There is also a tutorial article on perl.com.
 
K

kj

See Test::MockModule. There is also a tutorial article on perl.com.

Thanks for the pointer to the T::MM module; it looks like a useful
one.

But regarding that tutorial, when I searched for Test::MockModule
at perl.com there were no matches. What tutorial were you referring
to?

Thanks again (and thanks to Anno too),

kj
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,581
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top