How to redefine a sub during testing?

Discussion in 'Perl Misc' started by kj, Aug 17, 2006.

  1. kj

    kj Guest

    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

    --
    NOTE: In my address everything before the first period is backwards;
    and the last period, and everything after it, should be discarded.
     
    kj, Aug 17, 2006
    #1
    1. Advertising

  2. kj

    kj Guest

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

    kj


    In <ec238n$f4l$> kj <> writes:





    >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


    >--
    >NOTE: In my address everything before the first period is backwards;
    >and the last period, and everything after it, should be discarded.

    --
    NOTE: In my address everything before the first period is backwards;
    and the last period, and everything after it, should be discarded.
     
    kj, Aug 17, 2006
    #2
    1. Advertising

  3. kj

    -berlin.de Guest

    kj <> wrote in comp.lang.perl.misc:

    [...]

    > 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
     
    -berlin.de, Aug 17, 2006
    #3
  4. kj

    Peter Scott Guest

    On Thu, 17 Aug 2006 15:50:47 +0000, kj wrote:
    > 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.

    --
    Peter Scott
    http://www.perlmedic.com/
    http://www.perldebugged.com/
     
    Peter Scott, Aug 18, 2006
    #4
  5. kj

    kj Guest

    In <> Peter Scott <> writes:

    >On Thu, 17 Aug 2006 15:50:47 +0000, kj wrote:
    >> 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.


    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

    --
    NOTE: In my address everything before the first period is backwards;
    and the last period, and everything after it, should be discarded.
     
    kj, Aug 22, 2006
    #5
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. THY
    Replies:
    1
    Views:
    401
    Steve C. Orr, MCSD
    Aug 19, 2003
  2. Ben
    Replies:
    2
    Views:
    919
  3. traveller
    Replies:
    0
    Views:
    1,217
    traveller
    Jan 8, 2008
  4. Lawrence D'Oliveiro

    Death To Sub-Sub-Sub-Directories!

    Lawrence D'Oliveiro, May 5, 2011, in forum: Java
    Replies:
    92
    Views:
    2,083
    Lawrence D'Oliveiro
    May 20, 2011
  5. Dmitry Korolyov

    Datagrid not updated during delete, but updated during insert and update

    Dmitry Korolyov, Sep 22, 2003, in forum: ASP .Net Datagrid Control
    Replies:
    0
    Views:
    422
    Dmitry Korolyov
    Sep 22, 2003
Loading...

Share This Page