Skip Menu |

This queue is for tickets about the Test-MockObject CPAN distribution.

Report information
The Basics
Id: 14251
Status: resolved
Worked: 45 min
Priority: 0/
Queue: Test-MockObject

People
Owner: chromatic [...] cpan.org
Requestors: adamk [...] cpan.org
Cc:
AdminCc:

Bug Information
Severity: Critical
Broken in: 1.00
Fixed in: (no value)



Subject: Test::MockObject::Extends breaks AUTOLOAD
As I mentioned at OSCON, Test::MockObject::Extends badly breaks with anything that depends on AUTOLOAD. I've attached a complete test script for this case. It also threw up another bug as well I'd say is pretty critical, which is that even if a class is already loaded, unless it has it's own file, Test::MockObject::Extends explodes when trying to mock it, because it forces a require. :/ So anyways. Heres a complete test script, go for your life.
#!/usr/bin/perl -w # Regression Test # # The Problem: # When a class implements most of it's functionality via AUTOLOAD, # and does not have the option of creating specific methods for # every possible call (for example, there may be infinite possible # method names) creating a Test::MockObject::Extends with NOTHING # mocked should result in a "clear" object. # # That is, one that behaves as though it doesn't exist. At time of # writing, Test::MockObject::Extends would fatally break AUTOLOAD, # resulting in complete loss of functionality. # # This script creates such a "clear" extends object, and tests to # see that AUTOLOAD is still called correctly. BEGIN { chdir 't' if -d 't'; use lib '../lib'; } use strict; use Test::More tests => 11; use Test::Warn; my $module = 'Test::MockObject::Extends'; use_ok( $module ) or exit; ##################################################################### # The Test Class CLASS: { package Foo; use vars qw{$called_foo $called_autoload $method_name}; BEGIN { $called_foo = 0; $called_autoload = 0; $method_name = ''; } sub new { bless {}, $_[0]; } sub foo { $called_foo++; return 'foo'; } sub AUTOLOAD { $called_autoload++; $method_name = $Foo::AUTOLOAD; return 'autoload'; } 1; } ##################################################################### # Testing the Class my $object = Foo->new; isa_ok( $object, 'Foo' ); # A second bug here. # Test::MockObject::Extends can't mock a class that doesn't have it's own # module file. There are other ways to deal with this, see Class::Autouse # for the way it does it. my $mock = Test::MockObject::Extends->new( $object ); isa_ok( $mock, $module ); isa_ok( $mock, 'Foo' ); # Call foo is( scalar($mock->foo), 'foo', '->foo returns as expected' ); is( $Foo::called_foo, 1, '$called_foo is incremented' ); is( $Foo::called_autoload, 0, '$called_autoload is unchanged' ); is( $Foo::method_name, '', '$method_name is unchanged' ); # Call an autoloaded method is( scalar($mock->bar), 'autoload', '->bad returns as expected' ); is( $Foo::called_autoload, 1, '$called_autoload is unchanged' ); is( $Foo::method_name, 'Foo::bar', '$method_name is unchanged' );