stevieb has asked for the wisdom of the Perl Monks concerning the following question:

update: This was solved in this node, thanks to NetWallah in this reply. It boiled down to me not following through on reading documentation./update

I've got this code in the new() method of a DB class (code has been re-aligned as to not wrap here on PM):

$self->{db} = DBI->connect( "dbi:SQLite:dbname=$db_file", "", "", {RaiseError => 1} ) or die $DBI::errstr;

...and although I have tests that use this call hundreds of times, I wrote two specific tests to make both sides of the or pass:

{ # crash the connect() my $ok = eval { App::RPi::EnvUI::DB->new( db_file => '/' ); 1; }; is $ok, undef, "when a DBH can't be created, we die"; like $@, qr/unable to open database/, "...and the error message is sane"; } { # good connect() my $db = App::RPi::EnvUI::DB->new( testing => 1 ); is ref $db->{db}, 'DBI::db', "dbh loaded ok"; }

Both of those tests pass with no problems. However, when I run cover -test on the gamut, it shows this in the output:

23 50 T F unless $self->{'db'} = 'DBI'->connect("dbi:SQLite:dbname=$db +_file", '', '', {'RaiseError', 1})

Where the F (false) is covered, but the T (true) isn't. Line 23 is the DB connect code I showed above, and the 50 is telling me only half of the equation has been tested.

Am I missing something obvious here as to why I can't get 100% coverage on this branch?

This one branch is the only item keeping me from 100% coverage on this module.

To clarify, all tests pass before I view the coverage results:

Files=19, Tests=894, 83 wallclock secs ... Result: PASS

Replies are listed 'Best First'.
Re: Testing a DB connect() or die()
by NetWallah (Canon) on Oct 12, 2016 at 22:58 UTC
    RaiseError=>1
    Will cause "any method which results in an error will cause the DBI to effectively do a die" (From the DBI docs).

    So - it dies before it can execute your "or die".

    The docs suggest an "eval" to catch the "die".

            ...it is unhealthy to remain near things that are in the process of blowing up.     man page for WARP, by Larry Wall

      Per NetWallah's reply, I changed my code to this:

      $self->{db} = DBI->connect( "dbi:SQLite:dbname=$db_file", "", "", {RaiseError => $self->{db_err}} ) or die $DBI::errstr;

      ...and my tests to send in db_err => 0 in the calls to new(), and I get 100% coverage. I don't think I'll make this a user-visible param (but I will document it) as I always want the upper module to take care of the problem, but to ensure I've covered it, it works.

      This was a case of me not reading enough documentation.

      For the love of all things good. That's two issues in a row that I just didn't read enough documentation. (In a sad attempt to defend against my own ineptitude, I didn't think looking that high up in the docs, but that is far from reason).

      Thanks NetWallah, I'll make the RaiseError a method param or config variable for this specific test, and report back here with the results.

      Due to the numerous processes that are operating simultaneously in this application, it forces me to push test setup instructions far up the chain so that it can be tested without having the physical hardware I require (Raspberry Pi, and specific sensors attached). This one however, is something I should have noticed, but I digress... even though I haven't used DB in years, that's no excuse for me not reading the docs.