mayaTheCat has asked for the wisdom of the Perl Monks concerning the following question:
I want to mock files in my tests. I could not find any module that could help. So I wrote my own: Test::MockInputFile.
However, I had a couple of problems:
. I was able to mock files only for reading. Because I
cannot override the print builtin.
. I could not use a bareword as a file handler in the open
and close builtins. This is most probably due to my lack of knowledge on globs and prototypes.
I have the following questions on this subject:
. Is there already a module which does this job?
. Is the module I have written worth putting on CPAN?
. Do you have any suggestions on the problems I face?
package Test::MockInputFile; use strict; # --- my %file; sub define_file_mocker { my ($name, $content) = @_; $content ||= ''; $file{$name} = $content; } sub undefine_file_mocker { my ($name, $content) = @_; delete $file{$name}; } # --- sub import { my ($class, %arg) = @_; my $package = caller; _export_functions_to($package); my $module = defined $arg{module} ? $arg{module} : $package; _override_open_and_close_builtins_for($module); } # --- sub _export_functions_to { my ($package) = @_; no strict 'refs'; *{"$package\::define_file_mocker"} = \&define_file_mocker; *{"$package\::undefine_file_mocker"} = \&undefine_file_mocker; } # --- sub _override_open_and_close_builtins_for { my ($module) = @_; no strict 'refs'; *{"$module\::open"} = sub (\$$;$) { my ($fh, $mode, $name) = @_; if ($mode =~ /^<$/) { } elsif ($mode =~ /^<\s*([^<>].*)$/) { $name = $1; } else { $name = $mode; } # --- if (! defined $file{$name}) { # indicating; 'No such file or directory' $! = 2; return 0; } $$fh = Test::MockInputFile::Handler->new($name); return 1; }; *{"$module\::close"} = sub (\$) { my ($fh) = @_; undef $$fh; }; } # --- { package Test::MockInputFile::Handler; use overload '<>' => \&next_line; sub new { my ($class, $name) = @_; bless { content => $file{$name}, }, $class; } sub next_line { my ($self) = @_; if (! defined $self->{content}) { return undef; } my $line; if (! defined $/) { $line = $self->{content}; $self->{content} = undef; } elsif ($self->{content} =~ m;(.+?$/);s) { $line = $1; $self->{content} = $'; $self->{content} = undef if $self->{content} eq ''; } else { $line = $self->{content}; $self->{content} = undef; } return $line; } } # --- 1;
---------------------------------
life is ...
$mutation = sub { $_[0] =~ s/(.)/rand()<0.1?1-$1:$1/ge };
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: Mocking files for reading
by almut (Canon) on Sep 03, 2007 at 22:46 UTC | |
|
Re: Mocking files for reading
by grinder (Bishop) on Sep 04, 2007 at 08:14 UTC | |
|
Re: Mocking files for reading
by FunkyMonk (Bishop) on Sep 03, 2007 at 22:55 UTC | |
|
Re: Mocking files for reading
by jczeus (Monk) on Sep 04, 2007 at 14:38 UTC | |
|
Re: Mocking files for reading
by mayaTheCat (Scribe) on Sep 04, 2007 at 22:36 UTC |