Hi monks,

I'm trying to write a test which mocks a database connection. The code prepares the SQL statement and then executes it several times with differing bind parameters. This is what I tried using DBD::Mock:

use Test::More qw(no_plan); use strict; use warnings; use DBI; my $dbh = DBI->connect('dbi:Mock:','','' ); my @session_ar = ( { statement => "select foo,bar from baz where fi=?", bound_params => [ 1 ], results => [['foo','bar'], ['1foo','1bar']], }, { statement => "select foo,bar from baz where fi=?", bound_params => [ 2 ], results => [['foo','bar'], ['2foo','2bar']], }); my $session = DBD::Mock::Session->new(@session_ar); $dbh->{mock_session}=$session; my $sth = $dbh->prepare("select foo,bar from baz where fi=?"); for my $i (1..2) { $sth->execute($i); my @result=$sth->fetchrow_array(); is($result[0],"${i}foo","Got right foo"); is($result[1],"${i}bar","Got right bar"); }

Running this code with the current version of DBD::Mock gives an error on the second execute because of a wrong number of bound parameters:

ok 1 - Got right foo ok 2 - Got right bar DBD::Mock::st execute failed: Session Error: Not the same number of bo +und params in current state in DBD::Mock::Session (Session 1) at /usr +/share/perl5/DBD/Mock.pm line 1094. at t/90.dbd-mock.t line 28. not ok 3 - Got right foo # Failed test (t/90.dbd-mock.t at line 30) # got: undef # expected: '2foo' not ok 4 - Got right bar # Failed test (t/90.dbd-mock.t at line 31) # got: undef # expected: '2bar' 1..4 # Looks like you failed 2 tests of 4.

There's a bug report in RT regarding this problem. Trying to apply the 'fix' from the bug report gets me a little further:

ok 1 - Got right foo ok 2 - Got right bar not ok 3 - Got right foo # Failed test (t/90.dbd-mock.t at line 30) # got: '1foo' # expected: '2foo' not ok 4 - Got right bar # Failed test (t/90.dbd-mock.t at line 31) # got: '1bar' # expected: '2bar' 1..4 # Looks like you failed 2 tests of 4.

But it now returns the result from the first session entry even when called with the second value. If I move the prepare call into the loop it works correctly with and without the "fix", but that's not what I want to do in my code ;-). I tried using mock_add_results instead of DBD::Mock::Session, but that didn't work either.

I've looked through the DBD::Mock code for a bit, but it doesn't seem obvious to me how to add this behaviour and I'm in a bit of a rush to get this test written. Is there any way I can do this either with DBD::Mock or another module (short of setting up my own test database)? Thanks in advance.


Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it. -- Brian W. Kernighan

In reply to How to mock results to repeated $sth->execute() calls (DBD::Mock::Session) by tirwhan

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.