DBD :: Mock sets output values โ€‹โ€‹for stored procedure

I am trying to use DBD :: Mock to test code that uses a database. So far, normal SQL queries have worked fine, however, I was somewhat confused about how I can check the code that calls stored procedures. Using the bound_params key for the DBD::Mock::Session->new constructor, I can specify the input parameters, but I cannot find a way to configure the mock-up results of the parameters associated with DBI::StatementHandle::bind_param_inout() .

To provide an example for the code to be tested, look at the following:

 use DBI; my $dbh = DBI->connect('dbi:Mock', '', '', { RaiseError => 1, PrintError => 1 }); my $sth = $dbh->prepare(q{ BEGIN some_stored_proc(i_arg1 => :arg1, o_arg2 => :arg2); END; }); my ($arg1, $arg2) = ('foo', 'bar'); $sth->bind_param(':arg1', $arg1); $sth->bind_param_inout(':arg2', \$arg2, 200); $sth->execute(); print STDERR "OUTPUT VALUE OF arg2 = $arg2\n"; 

Now I want to put the DB with 'frobnication' for the arg2 parameter, so when executing the above code, the variable $arg2 contains this line, and the output

OUTPUTVALUE arg2 = frobnication

+4
source share
2 answers

Here is what I ended up doing. Essentially, the main job is to override the DBD::Mock::st::bind_param_inout .

 use DBI; use DBD::Mock; use DBD::Mock::st; use Carp; # array of values to be bound on each invocation my @values = qw/frobnication/; # dummy variable to trick DBD::Mock into thinking it got the same reference for # bind_param_inout and bound_params (the former is usually not in the control of # the testing code, hence this hack). my $dummy = undef; # keep reference to the original bind_param_inout method my $bind_param_inout_orig = \&DBD::Mock::st::bind_param_inout; # override with our mocked version that assigns a value to the reference. # notice that it does so at the bind_param_inout call, *NOT* the execute call! local *DBD::Mock::st::bind_param_inout = sub { my ($self, $param_num, $val, $size) = (shift, shift, shift, shift); $bind_param_inout_orig->($self, $param_num, \$dummy, $size, @_); $$val = shift @values or Carp::confess '@values array exhausted!'; }; # set up the mock session my $dbh = DBI->connect('dbi:Mock:', '', '', { RaiseError => 1, PrintError => 1 }); $dbh->{mock_session} = DBD::Mock::Session->new('foo_session' => ( { statement => qr/BEGIN\n\s*some_stored_proc/, results => [], bound_params => ['foo', \$dummy] })); # this is the code to be tested my $sth = $dbh->prepare(q{ BEGIN some_stored_proc(i_arg1 => :arg1, o_arg2 => :arg2); END; }); my ($arg1, $arg2) = ('foo', 'bar'); $sth->bind_param(':arg1', $arg1); $sth->bind_param_inout(':arg2', \$arg2, 200); $sth->execute(); print STDERR "OUTPUT VALUE OF arg2 = $arg2\n"; 
+1
source

You can use Sub :: Override to override this sub.

You can change your mocked object, like this one, and create new fakes.

 $mocked_dbd->mock( 'bind_param_inout',&mocked_bind_param_inout ); 

It seems to me that this method is taunted here: http://cpansearch.perl.org/src/DICHI/DBD-Mock-1.45/lib/DBD/Mock/st.pm

Maybe this will work:

 my @rs_foo = ( [ 'this', 'that' ], [ 'this_one', 'that_one' ], [ 'this_two', 'that_two' ], ); # the first one ordered $dbh->{mock_add_resultset} = [ @rs_foo ]; use Data::Dumper; my $mocked_records = $sth->{mock_records}; print Dumper($mock_records); 
0
source

All Articles