DVK
DVK

Reputation: 129403

What is the easiest way to test error handling when writing to a file in Perl?

I have a bog standard Perl file writing code with (hopefully) adequate error handling, of the type:

open(my $fh, ">", "$filename") or die "Could not open file $filname for writing: $!\n";
# Some code to get data to write
print $fh $data  or die "Could not write to file $filname: $!\n";
close $fh  or die "Could not close file $filname afterwriting: $!\n";
# No I can't use File::Slurp, sorry.

(I just wrote this code from memory, pardon any typos or bugs)

It is somewhat easy to test error handling in the first "die" line (for example, create a non-writable file with the same name you plan to write).

How can I test error handling in the second (print) and third (close) "die" lines?

The only way I know of to induce error when closing is to run out of space on filesystem while writing, which is NOT easy to do as a test.

I would prefer integration test type solutions rather than unit test type (which would involve mocking IO methods in Perl).

Upvotes: 5

Views: 636

Answers (2)

mob
mob

Reputation: 118605

Riffing on zdim's answer ...

Write to a file handle opened for reading.

Close a file handle that has already been closed.

Upvotes: 1

zdim
zdim

Reputation: 66883

Working with a bad filehandle will make them both fail

use warnings;
use strict;
use feature 'say';

my $file = shift || die "Usage: $0 out-filename\n";

open my $fh, '>', $file  or die "Can't open $file: $!";

$fh = \*10;

say $fh 'writes ok, ', scalar(localtime)  or warn "Can't write: $!";

close $fh or warn "Error closing: $!";

Prints

say() on unopened filehandle 10 at ...
Can't write: Bad file descriptor at ...
close() on unopened filehandle 10 at ...
Error closing: Bad file descriptor at ...

If you don't want to see perl's warnings capture them with $SIG{__WARN__} and print your messages to a file (or STDOUT), for example.

Upvotes: 5

Related Questions