views:

125

answers:

1

I have a Perl object that has defined use overload '""' => \&name; and a name method.

In my unit tests I have mocked this object, including the name method, but code like

if (-d $object)

still gives me Use of uninitialized value in -d .... The mocked method is not being executed.

My mock code:

my $CMmock = Test::MockObject::Extends->new('MyClass');
$CMmock->mock('name', sub { print "TEST!\n";});      
$CMmock->mock('""', sub {print "TEST!\n";});

Other methods that I have mocked are working.

A: 

[Overly complicated answer involving string evals elided.]

overload keeps an idea of what overloads are in effect in a magic place. Sometimes, especially with dynamically-generated classes, it fails to notice a change. You can force it to pay attention by blessing a fresh object into the class. You can immediately discard the object; the blessing event is what matters. You don't even have to store the object anywhere. The following works for me:

use Scalar::Util qw(blessed);

my $o = Test::MockObject::Extends->new('MyClass')
        ->mock(name => sub { "Bah!" })
;
bless {} => blessed $o;

print "$o\n";
darch
However, I'd like it noted that the overly complicated answer involving string evals was pretty awesome.
darch
Thanks for the answer. But this doesn't work for me. I probably phrased the question poorly. The actual mocking worked for me except for "-f" and "-d" operators. From the question that 'mobrule' linked, it seems that those operators cannot be mocked, at all. I'll probably use a solution where I replace "-d"/"-f" with some IO::File operation and mock IO::File, or create a method like "isFile { shift -f; }" and mock that instead.
Fredrik