in reply to Test::MockObject::Extends and FileHandle

You're missing a couple of things. First, you have to use the T::MO::E instance ($mock) rather than fake_new() here. fake_new() is for when you don't want to use the other class at all, which is not what you're doing.

Otherwise, the method form is really the best way I know of to make this code work. Perl 5's too clever in figuring out the indirect invocation syntax here.

Replies are listed 'Best First'.
Re^2: Test::MockObject::Extends and FileHandle
by SilasTheMonk (Chaplain) on Jan 23, 2010 at 10:40 UTC
    First, you have to use the T::MO::E instance ($mock) rather than fake_new() here. fake_new() is for when you don't want to use the other class at all, which is not what you're doing.
    chromatic, I am sorry this leaves me no wiser. What code exactly am I supposed to use instead of the fake_new line. If I comment out the fake_new line I can see that there is no faking at all. What advance did Wiley offer you for "Test::MockObject for dummies"? I think the book is needed.
      If I comment out the fake_new line I can see that there is no faking at all.

      Sure there is; pass an object to the T::MO::E constructor. The object you get back is your mock object. Any methods you add to that object are mock objects for that specific method. Thus you need to use that object (the T::MO::E instance), not a new object.

        > If I comment out the fake_new line I can see that there is no faking at all.

        Sure there is; pass an object to the T::MO::E constructor. The object you get back is your mock object. Any methods you add to that object are mock objects for that specific method. Thus you need to use that object (the T::MO::E instance), not a new object.

        Okay the scenario I have is that module X uses module FileHandle, in such a way that a single function X::f creates a FileHandle and writes to it all within one function. So I want one test script where FileHandle::open always fails, and one test script where FileHandle::open behaves normally but FileHandle::print always misbehaves. As far as I know I managed to get this working in the style I described above. How is one supposed to do that. If you are interested, you can see what I actually did in the latest version of Test::Regression.

        Maybe what I really need to do is write a Test::FileHandle module. As far as I can see all FileHandle does is import various functions. So presumably Test::FileHandle would import mocked functions into the FileHandle name space. I am not sure I fully understand how one would go about this. Would be nice if this worked for glob style classes in general and even better if the print syntax worked naturally.

      I tried this. Look in the home directory afterwards for "K":
      #!/usr/bin/perl use strict; use warnings; use FileHandle; use File::Tee qw(tee); use Test::MockObject::Extends; tee('STDOUT', '>>', 'stdout.txt'); my $mock= Test::MockObject::Extends->new(FileHandle->new); $mock->set_false( 'print' ); $mock->mock('FileHandle'); my $a = FileHandle->new; die "could not open" unless $a->open('>K'); die "I expect to die here" unless print {$a;} "hello"; die "I expect to be dead before we get to this point" unless $a->print("hello"); print $a;

        Khen1950fx,

        I downloaded your code scrap and it was definitely a completely unfaked FileHandle. Also what is the point of the File::Tee stuff? Surely that just complicates things.