Stories
Slash Boxes
Comments
NOTE: use Perl; is on undef hiatus. You can read content, but you can't post it. More info will be forthcoming forthcomingly.

All the Perl that's Practical to Extract and Report

The Fine Print: The following comments are owned by whoever posted them. We are not responsible for them in any way.
 Full
 Abbreviated
 Hidden
More | Login | Reply
Loading... please wait.
  • I'd also considered using a similar technique for similar scoping reasons. Make sure you're handling reentrancy correctly (although this may not be a problem if this technique is for unit testing).

    Would it be possible to show the code in which this is used? I'm having trouble thinking of a situation in which local woudn't cut it (although there obviously is if several different people have thought of this technique).

    I really like the name "scripting token". My first thought was to call the scalar a "canary"
    • I can give a little, though I think in most cases I didn't use it in as novel ways as I conceived that I would. (I'll have to redact a bit, but that's okay.) But I have a mean over-engineering streak...

      The method in the journal entry exists in my project Testing superclass (which isa Test::Class.) In addition, there is:

      sub mock_network {
          my $proto = shift;
          $proto->mock_class_constructor( NETWORK_PKG() . '::new', @_ );
      }
      sub mock_implementation {
          my $proto = shift;
          $proto->mock_class_constructor( IMPLEMENTATION_PKG() . '::new', @_ );
      }

      These are for mocking the layers of the library I'm testing (it's a specialized web service API.) In the class that tests the public API layer, I have:

      sub startup : Test(startup => 1) {
          my $self = shift;
          $self->SUPER::startup();
          my $test_class = $self->{test_class} = $TEST_CLASS;
          require_ok( $test_class) or $self->BAILOUT("Can't test class we can't require");
          my $impl_mocker = $self->{impl_mocker} = Test::MockObject->new();
          $impl_mocker->mock( ... );
          # etc etc
      }

      And later...

      sub test_03a_list_things : Tests {
          my $self = shift;
          my $cleanup_token = $self->mock_implementation( $self->{impl_mocker} );
          $self->_list_things(@_);
      }
      sub test_03b_list_things_integration : Tests {
          my $self = shift;
          my $net_mocker = $self->gen_net_mocker();
          my $cleanup_token = $self->mock_network( $net_mocker );
          $self->_list_things( $net_mocker, @_ );
      }

      The actual test code is in the _list_things() method. I'm just using lexical scoping here, but I get to move all the code that does the mocking to one place, and yet still have a lexical scope. (If I had used local, I would have had to repeat the actual mocking code every time I want to do this. Bad DRY!)

      Most of what I've done looks like this, it appears. But hey! Think of what I could do! I think I'm remembering now my initial motivation: it was DRY, per the example above.