package Moo::Role::DBIConnection { use Moo::Role; use DBI; has 'dbh' => ( is => 'ro', required => 1, coerce => sub { my $args = shift; return $args if ref($args) eq 'DBI::db'; ref($args) eq 'HASH' or die 'Not a DB handle nor a hashref'; return DBI->connect( @{$args}{qw/dsn user password options/} ); }, ); }; #### ## # testing package MyClass { use Moo; with 'Moo::Role::DBIConnection'; }; use Test::Most 'die'; my %args = ( dsn => 'dbi:mysql:database=mysql', user => 'ntonkin', password => undef, options => { RaiseError => 1 }, ); subtest 'With no args' => sub { dies_ok sub { my $o = MyClass->new }, 'exception on no args'; }; subtest 'With bad type' => sub { throws_ok { my $o = MyClass->new(dbh => [\%args]) } qr/Not a DB handle nor a hashref/; }; subtest 'With existing handle' => sub { my $dbh = DBI->connect( @args{qw/dsn user password options/} ); cmp_ok( $dbh->do('select count(*) from db'), '>', 0, 'Found a DB' ); my $o = new_ok('MyClass', [dbh => $dbh], 'No exception with handle passed in'); cmp_ok( $o->dbh->do('select count(*) from db'), '>', 0, 'Found a DB via obj'); }; subtest 'With bad params' => sub { local $args{user} = 'frobnicator'; throws_ok { my $o = MyClass->new(dbh => \%args) } qr/coercion for "dbh" failed/; throws_ok { my $o = MyClass->new(dbh => \%args) } qr/Access denied for user/; }; subtest 'With params' => sub { my $o = new_ok('MyClass', [dbh => \%args], 'No exception with args hash passed in'); cmp_ok( $o->dbh->do('select count(*) from db'), '>', 0, 'Found a DB via obj'); dies_ok sub { print $o->dsn }, 'No DSN accessor!'; }; done_testing; #### $ prove -lrv 11107494.pl 11107494.pl .. # Subtest: With no args ok 1 - exception on no args 1..1 ok 1 - With no args # Subtest: With bad type ok 1 - threw Regexp ((?^:Not a DB handle nor a hashref)) 1..1 ok 2 - With bad type # Subtest: With existing handle ok 1 - Found a DB ok 2 - 'No exception with handle passed in' isa 'MyClass' ok 3 - Found a DB via obj 1..3 ok 3 - With existing handle # Subtest: With bad params ok 1 - threw Regexp ((?^:coercion for "dbh" failed)) ok 2 - threw Regexp ((?^:Access denied for user)) 1..2 ok 4 - With bad params # Subtest: With params ok 1 - 'No exception with args hash passed in' isa 'MyClass' ok 2 - Found a DB via obj ok 3 - No DSN accessor! 1..3 ok 5 - With params 1..5 ok All tests successful. Files=1, Tests=5, 0 wallclock secs ( 0.01 usr 0.00 sys + 0.09 cusr 0.01 csys = 0.11 CPU) Result: PASS