4

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).

DVK
  • 126,886
  • 32
  • 213
  • 327
  • 2
    Related: https://stackoverflow.com/q/1361518/2404501 –  Apr 30 '19 at 20:17
  • And along the same lines but simpler: [`/dev/full`](https://en.wikipedia.org/wiki/%2Fdev%2Ffull) - it's like `/dev/null` for reading, but always fails when writing. –  Apr 30 '19 at 21:15

2 Answers2

5

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.

zdim
  • 64,580
  • 5
  • 52
  • 81
1

Riffing on zdim's answer ...

Write to a file handle opened for reading.

Close a file handle that has already been closed.

mob
  • 117,087
  • 18
  • 149
  • 283
  • I like this answer technically; but it does not solve the problem of how to test a **good, correct** code that I have in a working program, which doesn't do either of those two things :) – DVK Apr 30 '19 at 23:47
  • I think the idea is to _add this_ to a "good, correct" code, as a test – zdim Feb 21 '20 at 18:00