1DBD::Mock(3pm)        User Contributed Perl Documentation       DBD::Mock(3pm)
2
3
4

NAME

6       DBD::Mock - Mock database driver for testing
7

SYNOPSIS

9           use DBI;
10
11           # connect to your as normal, using 'Mock' as your driver name
12           my $dbh = DBI->connect( 'DBI:Mock:', '', '' )
13               || die "Cannot create handle: $DBI::errstr\n";
14
15           # create a statement handle as normal and execute with parameters
16           my $sth = $dbh->prepare( 'SELECT this, that FROM foo WHERE id = ?' );
17           $sth->execute( 15 );
18
19           # Now query the statement handle as to what has been done with it
20           my $mock_params = $sth->{mock_params};
21           print "Used statement: ", $sth->{mock_statement}, "\n",
22              "Bound parameters: ", join( ', ', @{ $mock_params } ), "\n";
23

DESCRIPTION

25       Testing with databases can be tricky. If you are developing a system
26       married to a single database then you can make some assumptions about
27       your environment and ask the user to provide relevant connection
28       information. But if you need to test a framework that uses DBI,
29       particularly a framework that uses different types of persistence
30       schemes, then it may be more useful to simply verify what the framework
31       is trying to do -- ensure the right SQL is generated and that the
32       correct parameters are bound. "DBD::Mock" makes it easy to just modify
33       your configuration (presumably held outside your code) and just use it
34       instead of "DBD::Foo" (like DBD::Pg or DBD::mysql) in your framework.
35
36       There is no distinct area where using this module makes sense. (Some
37       people may successfully argue that this is a solution looking for a
38       problem...) Indeed, if you can assume your users have something like
39       DBD::AnyData or DBD::SQLite or if you do not mind creating a dependency
40       on them then it makes far more sense to use these legitimate driver
41       implementations and test your application in the real world -- at least
42       as much of the real world as you can create in your tests...
43
44       And if your database handle exists as a package variable or something
45       else easily replaced at test-time then it may make more sense to use
46       Test::MockObject to create a fully dynamic handle. There is an
47       excellent article by chromatic about using Test::MockObject in this and
48       other ways, strongly recommended. (See "SEE ALSO" for a link)
49
50   How does it work?
51       "DBD::Mock" comprises a set of classes used by DBI to implement a
52       database driver. But instead of connecting to a datasource and
53       manipulating data found there it tracks all the calls made to the
54       database handle and any created statement handles. You can then inspect
55       them to ensure what you wanted to happen actually happened. For
56       instance, say you have a configuration file with your database
57       connection information:
58
59           [DBI]
60           dsn      = DBI:Pg:dbname=myapp
61           user     = foo
62           password = bar
63
64       And this file is read in at process startup and the handle stored for
65       other procedures to use:
66
67           package ObjectDirectory;
68
69           my ( $DBH );
70
71           sub run_at_startup {
72               my ( $class, $config ) = @_;
73               $config ||= read_configuration( ... );
74               my $dsn  = $config->{DBI}{dsn};
75               my $user = $config->{DBI}{user};
76               my $pass = $config->{DBI}{password};
77               $DBH = DBI->connect( $dsn, $user, $pass ) || die ...;
78           }
79
80           sub get_database_handle {
81               return $DBH;
82           }
83
84       A procedure might use it like this (ignoring any error handling for the
85       moment):
86
87           package My::UserActions;
88
89           sub fetch_user {
90               my ( $class, $login ) = @_;
91               my $dbh = ObjectDirectory->get_database_handle;
92               my $sql = q{
93                   SELECT login_name, first_name, last_name, creation_date, num_logins
94                   FROM users
95                   WHERE login_name = ?
96               };
97               my $sth = $dbh->prepare( $sql );
98               $sth->execute( $login );
99               my $row = $sth->fetchrow_arrayref;
100               return ( $row ) ? User->new( $row ) : undef;
101         }
102
103       So for the purposes of our tests we just want to ensure that:
104
105       1. The right SQL is being executed
106       2. The right parameters are bound
107
108       Assume whether the SQL actually works or not is irrelevant for this
109       test :-)
110
111       To do that our test might look like:
112
113           my $config = ObjectDirectory->read_configuration( ... );
114           $config->{DBI}{dsn} = 'DBI:Mock:';
115           ObjectDirectory->run_at_startup( $config );
116
117           my $login_name = 'foobar';
118           my $user = My::UserActions->fetch_user( $login_name );
119
120           # Get the handle from ObjectDirectory;
121           # this is the same handle used in the
122           # 'fetch_user()' procedure above
123           my $dbh = ObjectDirectory->get_database_handle();
124
125           # Ask the database handle for the history
126           # of all statements executed against it
127           my $history = $dbh->{mock_all_history};
128
129           # Now query that history record to
130           # see if our expectations match reality
131           is(scalar(@{$history}), 1, 'Correct number of statements executed' ;
132
133           my $login_st = $history->[0];
134           like($login_st->statement,
135               qr/SELECT login_name.*FROM users WHERE login_name = ?/sm,
136               'Correct statement generated' );
137
138           my $params = $login_st->bound_params;
139           is(scalar(@{$params}), 1, 'Correct number of parameters bound');
140           is($params->[0], $login_name, 'Correct value for parameter 1' );
141
142           # Reset the handle for future operations
143           $dbh->{mock_clear_history} = 1;
144
145       The list of properties and what they return is listed below. But in an
146       overall view:
147
148       •   A database handle contains the history of all statements created
149           against it.  Other properties set for the handle (e.g.,
150           "PrintError", "RaiseError") are left alone and can be queried as
151           normal, but they do not affect anything. (A future feature may
152           track the sequence/history of these assignments but if there is no
153           demand it probably will not get implemented.)
154
155       •   A statement handle contains the statement it was prepared with plus
156           all bound parameters or parameters passed via execute(). It can
157           also contain predefined results for the statement handle to
158           "fetch", track how many fetches were called and what its current
159           record is.
160
161   A Word of Warning
162       This may be an incredibly naive implementation of a DBD. But it works
163       for me...
164

DBD::Mock

166       Since this is a normal DBI statement handle we need to expose our
167       tracking information as properties (accessed like a hash) rather than
168       methods.
169
170   Database Driver Properties
171       "mock_connect_fail"
172           This is a boolean property which when set to true (1) will not
173           allow DBI to connect. This can be used to simulate a DSN error or
174           authentication failure.  This can then be set back to false (0) to
175           resume normal DBI operations. Here is an example of how this works:
176
177               # install the DBD::Mock driver
178               my $drh = DBI->install_driver('Mock');
179
180               $drh->{mock_connect_fail} = 1;
181
182               # this connection will fail
183               my $dbh = DBI->connect('dbi:Mock:', '', '') || die "Cannot connect";
184
185               # this connection will throw an exception
186               my $dbh = DBI->connect('dbi:Mock:', '', '', { RaiseError => 1 });
187
188               $drh->{mock_connect_fail} = 0;
189
190               # this will work now ...
191               my $dbh = DBI->connect(...);
192
193           This feature is conceptually different from the "mock_can_connect"
194           attribute of the $dbh in that it has a driver-wide scope, where
195           "mock_can_connect" is handle-wide scope. It also only prevents the
196           initial connection, any $dbh handles created prior to setting
197           "mock_connect_fail" to true (1) will still go on working just fine.
198
199       "mock_data_sources"
200           This is an ARRAY reference which holds fake data sources which are
201           returned by the Driver and Database Handle's data_source() method.
202
203       "mock_add_data_sources"
204           This takes a string and adds it to the "mock_data_sources"
205           attribute.
206
207   Database Handle Properties
208       "mock_all_history"
209           Returns an array reference with all history (a.k.a.
210           "DBD::Mock::StatementTrack") objects created against the database
211           handle in the order they were created. Each history object can then
212           report information about the SQL statement used to create it, the
213           bound parameters, etc..
214
215       "mock_all_history_iterator"
216           Returns a "DBD::Mock::StatementTrack::Iterator" object which will
217           iterate through the current set of "DBD::Mock::StatementTrack"
218           object in the history.  See the
219           "DBD::Mock::StatementTrack::Iterator" documentation below for more
220           information.
221
222       "mock_clear_history"
223           If set to a true value all previous statement history operations
224           will be erased. This includes the history of currently open
225           handles, so if you do something like:
226
227               my $dbh = get_handle( ... );
228               my $sth = $dbh->prepare( ... );
229               $dbh->{mock_clear_history} = 1;
230               $sth->execute( 'Foo' );
231
232           You will have no way to learn from the database handle that the
233           statement parameter 'Foo' was bound.
234
235           This is useful mainly to ensure you can isolate the statement
236           histories from each other. A typical sequence will look like:
237
238               set handle to framework
239               perform operations
240               analyze mock database handle
241               reset mock database handle history
242               perform more operations
243               analyze mock database handle
244               reset mock database handle history
245               ...
246
247       "mock_can_connect"
248           This statement allows you to simulate a downed database connection.
249           This is useful in testing how your application/tests will perform
250           in the face of some kind of catastrophic event such as a network
251           outage or database server failure.  It is a simple boolean value
252           which defaults to on, and can be set like this:
253
254               # turn the database off
255               $dbh->{mock_can_connect} = 0;
256
257               # turn it back on again
258               $dbh->{mock_can_connect} = 1;
259
260           The statement handle checks this value as well, so something like
261           this will fail in the expected way:
262
263               $dbh = DBI->connect( 'DBI:Mock:', '', '' );
264               $dbh->{mock_can_connect} = 0;
265
266               # blows up!
267               my $sth = eval { $dbh->prepare( 'SELECT foo FROM bar' ) });
268               if ( $@ ) {
269                   # Here, $DBI::errstr = 'No connection present'
270               }
271
272           Turning off the database after a statement prepare will fail on the
273           statement execute(), which is hopefully what you would expect:
274
275               $dbh = DBI->connect( 'DBI:Mock:', '', '' );
276
277               # ok!
278               my $sth = eval { $dbh->prepare( 'SELECT foo FROM bar' ) });
279               $dbh->{mock_can_connect} = 0;
280
281               # blows up!
282               $sth->execute;
283
284           Similarly:
285
286               $dbh = DBI->connect( 'DBI:Mock:', '', '' );
287
288               # ok!
289               my $sth = eval { $dbh->prepare( 'SELECT foo FROM bar' ) });
290
291               # ok!
292               $sth->execute;
293
294               $dbh->{mock_can_connect} = 0;
295
296               # blows up!
297               my $row = $sth->fetchrow_arrayref;
298
299           Note: The handle attribute "Active" and the handle method "ping"
300           will behave according to the value of "mock_can_connect". So if
301           "mock_can_connect" were to be set to 0 (or off), then both "Active"
302           and "ping" would return false values (or 0).
303
304       "mock_add_resultset( \@resultset | \%resultset_and_options )"
305           This stocks the database handle with a record set, allowing you to
306           seed data for your application to see if it works properly. Each
307           recordset is a simple arrayref of arrays with the first arrayref
308           being the field names used. Every time a statement handle is
309           created it asks the database handle if it has any resultsets
310           available and if so uses it.
311
312           Here is a sample usage, partially from the test suite:
313
314               my @user_results = (
315                   [ 'login', 'first_name', 'last_name' ],
316                   [ 'cwinters', 'Chris', 'Winters' ],
317                   [ 'bflay', 'Bobby', 'Flay' ],
318                   [ 'alincoln', 'Abe', 'Lincoln' ],
319               );
320               my @generic_results = (
321                   [ 'foo', 'bar' ],
322                   [ 'this_one', 'that_one' ],
323                   [ 'this_two', 'that_two' ],
324               );
325
326               my $dbh = DBI->connect( 'DBI:Mock:', '', '' );
327               $dbh->{mock_add_resultset} = \@user_results;    # add first resultset
328               $dbh->{mock_add_resultset} = \@generic_results; # add second resultset
329               my ( $sth );
330               eval {
331                   $sth = $dbh->prepare( 'SELECT login, first_name, last_name FROM foo' );
332                   $sth->execute();
333               };
334
335               # this will fetch rows from the first resultset...
336               my $row1 = $sth->fetchrow_arrayref;
337               my $user1 = User->new( login => $row->[0],
338                                      first => $row->[1],
339                                      last  => $row->[2] );
340               is( $user1->full_name, 'Chris Winters' );
341
342               my $row2 = $sth->fetchrow_arrayref;
343               my $user2 = User->new( login => $row->[0],
344                                      first => $row->[1],
345                                      last  => $row->[2] );
346               is( $user2->full_name, 'Bobby Flay' );
347               ...
348
349               my $sth_generic = $dbh->prepare( 'SELECT foo, bar FROM baz' );
350               $sth_generic->execute;
351
352               # this will fetch rows from the second resultset...
353               my $row = $sth->fetchrow_arrayref;
354
355           It is possible to assign a hashref where the resultset must be
356           given as value for the "results" key:
357
358               $dbh->{mock_add_resultset} = {
359                   results => [
360                       [ 'foo', 'bar' ],
361                       [ 'this_one', 'that_one' ],
362                       [ 'this_two', 'that_two' ],
363                   ],
364               };
365
366           The reason for the hashref form is that you can add options as
367           described in the following.
368
369           You can associate a resultset with a particular SQL statement
370           instead of adding them in the order they will be fetched:
371
372               $dbh->{mock_add_resultset} = {
373                   sql     => 'SELECT foo, bar FROM baz',
374                   results => [
375                       [ 'foo', 'bar' ],
376                       [ 'this_one', 'that_one' ],
377                       [ 'this_two', 'that_two' ],
378                   ],
379               };
380
381           This will return the given results when the statement '"SELECT foo,
382           bar FROM baz"' is prepared/executed. Note that they will be
383           returned every time the statement is prepared/executed, not just
384           the first.  It should also be noted that if you want, for some
385           reason, to change the result set bound to a particular SQL
386           statement, all you need to do is add the result set again with the
387           same SQL statement and "DBD::Mock" will overwrite it.
388
389           If the "sql" parameter is a regular expression reference then the
390           results will be returned for any SQL statements that matches it:
391
392               $dbh->{mock_add_resultset} = {
393                   sql     => qr/^SELECT foo FROM/i,
394                   results => [
395                       [ 'foo' ],
396                       [ 'this_one' ],
397                   ],
398               };
399
400           If an SQL statement matches both a specified SQL statement result
401           set and a regular expression result set then the specified SQL
402           statement takes precedence.  If two regular expression result sets
403           match then the first one added takes precedence:
404
405               # Set up our first regex matching result set
406               $dbh->{mock_add_resultset} = {
407                   sql => qr/^SELECT foo/,
408                   results => [ [ 'foo' ], [ 200 ] ],
409               };
410
411               # Set up our second regex matching result set
412               #   Note - This results set would never be used as the one above will match
413               #   and thus take precedence
414               $dbh->{mock_add_resultset} = {
415                   sql => qr/^SELECT foo FROM/,
416                   results => [ [ 'foo' ], [ 300 ] ],
417               };
418
419               # Set up our first statically defined result set
420               # This result set will take precedence over the regex matching ones above
421               $dbh->{mock_add_resultset} = {
422                   sql => 'SELECT foo FROM bar',
423                   results => [[ 'foo' ], [ 50 ]]
424               };
425
426               # This query will be served by the first regex matching result set
427               my $sth = $dbh->prepare('SELECT foo FROM oof');
428               $sth->execute()
429
430               my ($result) = $sth->fetchrow_array();
431               is( $result, 200 );
432
433               # This quere will be served by the statically defined result set
434               $sth = $dbh->prepare('SELECT foo FROM bar');
435               $sth->execute();
436
437               my ($result2) = $sth->fetchrow_array();
438               is( $result2, 50 );
439
440           It should also be noted that the "rows" method will return the
441           number of records stocked in the result set. So if your
442           code/application makes use of the "$sth->rows" method for things
443           like "UPDATE" and "DELETE" calls you should stock the result set
444           like so:
445
446               $dbh->{mock_add_resultset} = {
447                   sql     => 'UPDATE foo SET baz = 1, bar = 2',
448                   # this will appear to have updated 3 rows
449                   results => [[ 'rows' ], [], [], []],
450               };
451
452               # or ...
453
454               $dbh->{mock_add_resultset} = {
455                   sql     => 'DELETE FROM foo WHERE bar = 2',
456                   # this will appear to have deleted 1 row
457                   results => [[ 'rows' ], []],
458               };
459
460           Now I admit this is not the most elegant way to go about this, but
461           it works for me for now, and until I can come up with a better
462           method, or someone sends me a patch ;) it will do for now.
463
464           If you want a given statement to fail, you will have to use the
465           hashref method and add a "failure" key. That key must be handed an
466           arrayref with the error number and error string, in that order.
467
468               $dbh->{mock_add_resultset} = {
469                   sql => 'SELECT foo FROM bar',
470                   results => DBD::Mock->NULL_RESULTSET,
471                   failure => [ 5, 'Ooops!' ],
472               };
473
474           Without the "sql" attribute the next statement will fail in any
475           case:
476
477               $dbh->{mock_add_resultset} = {
478                   results => DBD::Mock->NULL_RESULTSET,
479                   failure => [ 5, 'Ooops!' ],
480               };
481
482       "mock_get_info"
483           This attribute can be used to set up values for get_info(). It
484           takes a hashref of attribute_name/value pairs. See DBI for more
485           information on the information types and their meaning.
486
487       "mock_session"
488           This attribute can be used to set a current "DBD::Mock::Session"
489           object. For more information on this, see the "DBD::Mock::Session"
490           docs below. This attribute can also be used to remove the current
491           session from the $dbh simply by setting it to "undef".
492
493       "mock_last_insert_id"
494           This attribute is incremented each time an "INSERT" statement is
495           passed to "prepare" on a per-handle basis. It's starting value can
496           be set with the "mock_start_insert_id" attribute (see below).
497
498               $dbh->{mock_start_insert_id} = 10;
499
500               my $sth = $dbh->prepare('INSERT INTO Foo (foo, bar) VALUES(?, ?)');
501
502               $sth->execute(1, 2);
503               # $dbh->{mock_last_insert_id} == 10
504
505               $sth->execute(3, 4);
506               # $dbh->{mock_last_insert_id} == 11
507
508           For more examples, please refer to the test file
509           t/025_mock_last_insert_id.t.
510
511           To access "last_insert_id" using driver specific attributes like
512           "mysql_insertid" and "mariadb_insertid" then you can use "Attribute
513           Aliasing".
514
515       "mock_start_insert_id"
516           This attribute can be used to set a start value for the
517           "mock_last_insert_id" attribute. It can also be used to effectively
518           reset the "mock_last_insert_id" attribute as well.
519
520           This attribute also can be used with an ARRAY ref parameter, it's
521           behavior is slightly different in that instead of incrementing the
522           value for every "prepare" it will only increment for each
523           "execute". This allows it to be used over multiple "execute" calls
524           in a single $sth. It's usage looks like this:
525
526               $dbh->{mock_start_insert_id} = [ 'Foo', 10 ];
527               $dbh->{mock_start_insert_id} = [ 'Baz', 20 ];
528
529               my $sth1 = $dbh->prepare('INSERT INTO Foo (foo, bar) VALUES(?, ?)');
530
531               my $sth2 = $dbh->prepare('INSERT INTO Baz (baz, buz) VALUES(?, ?)');
532
533               $sth1->execute(1, 2);
534               # $dbh->{mock_last_insert_id} == 10
535
536               $sth2->execute(3, 4);
537               # $dbh->{mock_last_insert_id} == 20
538
539           Note that "DBD::Mock"'s matching of table names in "INSERT"
540           statements is fairly simple, so if your table names are quoted in
541           the insert statement ("INSERT INTO "Foo"") then you need to quote
542           the name for "mock_start_insert_id":
543
544               $dbh->{mock_start_insert_id} = [ q{"Foo"}, 10 ];
545
546       "mock_add_parser"
547           DBI provides some simple parsing capabilities for "SELECT"
548           statements to ensure that placeholders are bound properly. And
549           typically you may simply want to check after the fact that a
550           statement is syntactically correct, or at least what you expect.
551
552           But other times you may want to parse the statement as it is
553           prepared rather than after the fact. There is a hook in this mock
554           database driver for you to provide your own parsing routine or
555           object.
556
557           The syntax is simple:
558
559               $dbh->{mock_add_parser} = sub {
560                   my ( $sql ) = @_;
561                   unless ( $sql =~ /some regex/ ) {
562                       die "does not contain secret fieldname";
563                   }
564               };
565
566           You can also add more than one for a handle. They will be called in
567           order, and the first one to fail will halt the parsing process:
568
569               $dbh->{mock_add_parser} = \&parse_update_sql;
570               $dbh->{mock_add-parser} = \&parse_insert_sql;
571
572           Depending on the "PrintError" and "RaiseError" settings in the
573           database handle any parsing errors encountered will issue a "warn"
574           or "die". No matter what the statement handle will be "undef".
575
576           Instead of providing a subroutine reference you can use an object.
577           The only requirement is that it implements the method parse() and
578           takes a SQL statement as the only argument. So you should be able
579           to do something like the following (untested):
580
581               my $parser = SQL::Parser->new( 'mysql', { RaiseError => 1 } );
582               $dbh->{mock_add_parser} = $parser;
583
584       "mock_data_sources" & "mock_add_data_sources"
585           These properties will dispatch to the Driver's properties of the
586           same name.
587
588   Attribute Aliasing
589       Basically this feature allows you to alias attributes to other
590       attributes. So for instance, you can alias a commonly expected
591       attribute like "mysql_insertid" to something "DBD::Mock" already has
592       like "mock_last_insert_id". While you can also just set
593       "mysql_insertid" yourself, this functionality allows it to take
594       advantage of things like the autoincrementing of the
595       "mock_last_insert_id" attribute.
596
597       The functionality is off by default so as to not cause any issues with
598       backwards compatibility, but can easily be turned on and off like this:
599
600           # turn it on
601           $DBD::Mock::AttributeAliasing++;
602
603           # turn it off
604           $DBD::Mock::AttributeAliasing = 0;
605
606       Once this is turned on, you will need to choose a database specific
607       attribute aliasing table like so:
608
609           DBI->connect('dbi:Mock:MySQL', '', '');
610
611       Or, by using the database name if using driver DSNs:
612
613           DBI->connect('dbi:Mock:host=localhost;port=3306;database=MySQL', '', '');
614
615       The "MySQL" in the DSN will be picked up and the MySQL specific
616       attribute aliasing will be used.
617
618       Right now there is only minimal support for MySQL and MariaDB:
619
620       MySQL
621           Currently the "mysql_insertid" attribute for $dbh and $sth are
622           aliased to the $dbh attribute "mock_last_insert_id".
623
624       MariaDB
625           Currently the "mariadb_insertid" attribute for $dbh and $sth are
626           aliased to the $dbh attribute "mock_last_insert_id".
627
628       It is possible to add more aliases though, using the
629       "DBD::Mock:_set_mock_attribute_aliases" function (see the source code
630       for details)
631
632   Database Driver Methods
633       "last_insert_id"
634           This returns the value of "mock_last_insert_id".
635
636       In order to capture begin_work(), commit(), and rollback(), "DBD::Mock"
637       will create statements for them, as if you had issued them in the
638       appropriate SQL command line program. They will go through the standard
639       prepare()-execute() cycle, meaning that any custom SQL parsers will be
640       triggered and "DBD::Mock::Session" will need to know about these
641       statements.
642
643       "begin_work"
644           This will create a statement with SQL of "BEGIN WORK" and no
645           parameters.
646
647       "commit"
648           This will create a statement with SQL of "COMMIT" and no
649           parameters.
650
651       "rollback"
652           This will create a statement with SQL of "ROLLBACK" and no
653           parameters.
654
655   Statement Handle Properties
656       "Active"
657           Returns true if the handle is a "SELECT" and has more records to
658           fetch, false otherwise. (From the DBI.)
659
660       "mock_statement"
661           The SQL statement this statement handle was "prepare"d with. So if
662           the handle was created with:
663
664               my $sth = $dbh->prepare( 'SELECT * FROM foo' );
665
666           This would return:
667
668               SELECT * FROM foo
669
670           The original statement is unmodified so if you are checking against
671           it in tests you may want to use a regex rather than a straight
672           equality check. (However if you use a phrasebook to store your SQL
673           externally you are a step ahead...)
674
675       "mock_fields"
676           Fields used by the statement. As said elsewhere we do no analysis
677           or parsing to find these, you need to define them beforehand. That
678           said, you do not actually need this very often.
679
680           Note that this returns the same thing as the normal statement
681           property "FIELD".
682
683       "mock_params"
684           Returns an arrayref of parameters bound to this statement in the
685           order specified by the bind type. For instance, if you created and
686           stocked a handle with:
687
688               my $sth = $dbh->prepare( 'SELECT * FROM foo WHERE id = ? AND is_active = ?' );
689               $sth->bind_param( 2, 'yes' );
690               $sth->bind_param( 1, 7783 );
691
692           This would return:
693
694               [ 7738, 'yes' ]
695
696           The same result will occur if you pass the parameters via execute()
697           instead:
698
699               my $sth = $dbh->prepare( 'SELECT * FROM foo WHERE id = ? AND is_active = ?' );
700               $sth->execute( 7783, 'yes' );
701
702           The same using named parameters
703
704               my $sth = $dbh->prepare( 'SELECT * FROM foo WHERE id = :id AND is_active = :active' );
705               $sth->bind_param( ':id' => 7783 );
706               $sth->bind_param( ':active' => 'yes' );
707
708       "mock_param_attrs"
709           Returns an arrayref of any attributes (parameter type) defined for
710           bound parameters (note: you rarely need to define attributes for
711           bound parameters).  Where an attribute/type hasn't been that slot
712           in the returned arrayref will be "undef". e.g. for:
713
714               my $sth = $dbh->prepare( 'SELECT * FROM foo WHERE id = ? AND is_active = ?' );
715               $sth->bind_param( 2, 'yes' );
716               $sth->bind_param( 1 7783, SQL_INTEGER );
717
718           This would return:
719
720               [ SQL_INTEGER, undef ]
721
722           Passing parameters via execute() will always populate the array
723           with "undef", so for:
724
725               $sth->execute( 7783, 'yes' );
726
727           This would return:
728
729               [ undef, undef ]
730
731       "mock_execution_history"
732           Returns an arrayref where each entry contains the details for an
733           execution of the prepared statement. e.g. after:
734
735               my $sth = $dbh->prepare( 'SELECT * FROM foo WHERE id = ? AND is_active = ?' );
736               $sth->bind_param( 2, 'yes' );
737               $sth->bind_param( 1 7783, SQL_INTEGER );
738               $sth->execute();
739
740               $sth->execute( 1023, 'no' );
741
742           Then "$sth->{mock_execution_history}" would be:
743
744               [
745                   {
746                       params => [ 7783, 'yes' ],
747                       attrs  => [ SQL_INTEGER, undef ],
748                   }, {
749                       params => [ 1023, 'no' ],
750                       attrs  => [ undef, undef ],
751                   }
752               ]
753
754       "mock_records"
755           An arrayref of arrayrefs representing the records the mock
756           statement was stocked with.
757
758       "mock_num_records"
759           Number of records the mock statement was stocked with; if never
760           stocked it is still 0. (Some weirdos might expect undef...)
761
762       "mock_num_rows"
763           This returns the same value as mock_num_records. And is what is
764           returned by the "rows" method of the statement handle.
765
766       "mock_current_record_num"
767           Current record the statement is on; returns 0 in the instances when
768           you have not yet called execute() and if you have not yet called a
769           "fetch" method after the execute.
770
771       "mock_is_executed"
772           Whether execute() has been called against the statement handle.
773           Returns 'yes' if so, 'no' if not.
774
775       "mock_is_finished"
776           Whether finish() has been called against the statement handle.
777           Returns 'yes' if so, 'no' if not.
778
779       "mock_is_depleted"
780           Returns 'yes' if all the records in the recordset have been
781           returned. If no fetch() was executed against the statement, or If
782           no return data was set this will return 'no'.
783
784       "mock_my_history"
785           Returns a "DBD::Mock::StatementTrack" object which tracks the
786           actions performed by this statement handle. Most of the actions are
787           separately available from the properties listed above, so you
788           should never need this.
789

DBD::Mock::Pool

791       This module can be used to emulate Apache::DBI style DBI connection
792       pooling.  Just as with "Apache::DBI", you must enable "DBD::Mock::Pool"
793       before loading DBI.
794
795           use DBD::Mock qw(Pool);
796           # followed by ...
797           use DBI;
798
799       While this may not seem to make a lot of sense in a single-process
800       testing scenario, it can be useful when testing code which assumes a
801       multi-process "Apache::DBI" pooled environment.
802

DBD::Mock::StatementTrack

804       Under the hood this module does most of the work with a
805       "DBD::Mock::StatementTrack" object. This is most useful when you are
806       reviewing multiple statements at a time, otherwise you might want to
807       use the "mock_*" statement handle attributes instead.
808
809       new( %params )
810           Takes the following parameters:
811
812"return_data": Arrayref of return data records
813
814"fields": Arrayref of field names
815
816"bound_params": Arrayref of bound parameters
817
818"bound_param_attrs": Arrayref of bound parameter attributes
819
820       "statement" (Statement attribute "mock_statement")
821           Gets/sets the SQL statement used.
822
823       "fields"  (Statement attribute "mock_fields")
824           Gets/sets the fields to use for this statement.
825
826       "bound_params"  (Statement attribute "mock_params")
827           Gets/set the bound parameters to use for this statement.
828
829       "return_data"  (Statement attribute "mock_records")
830           Gets/sets the data to return when asked (that is, when someone
831           calls "fetch" on the statement handle).
832
833       "current_record_num" (Statement attribute "mock_current_record_num")
834           Gets/sets the current record number.
835
836       is_active() (Statement attribute "Active")
837           Returns true if the statement is a "SELECT" and has more records to
838           fetch, false otherwise. (This is from the DBI, see the 'Active'
839           docs under 'ATTRIBUTES COMMON TO ALL HANDLES'.)
840
841       is_executed( $yes_or_no ) (Statement attribute "mock_is_executed")
842           Sets the state of the tracker "executed" flag.
843
844       is_finished( $yes_or_no ) (Statement attribute "mock_is_finished")
845           If set to "yes" tells the tracker that the statement is finished.
846           This resets the current record number to 0 and clears out the array
847           ref of returned records.
848
849       is_depleted() (Statement attribute "mock_is_depleted")
850           Returns true if the current record number is greater than the
851           number of records set to return.
852
853       "num_fields"
854           Returns the number of fields set in the "fields" parameter.
855
856       "num_rows"
857           Returns the number of records in the current result set.
858
859       "num_params"
860           Returns the number of parameters set in the "bound_params"
861           parameter.
862
863       "bound_param( $param_num, $value )"
864           Sets bound parameter $param_num to $value. Returns the arrayref of
865           currently-set bound parameters. This corresponds to the
866           "bind_param" statement handle call.
867
868       bound_param_trailing( @params )
869           Pushes @params onto the list of already-set bound parameters.
870
871       mark_executed()
872           Tells the tracker that the statement has been executed and resets
873           the current record number to 0.
874
875       next_record()
876           If the statement has been depleted (all records returned) returns
877           "undef"; otherwise it gets the current record for returning,
878           increments the current record number and returns the current
879           record.
880
881       to_string()
882           Tries to give a decent depiction of the object state for use in
883           debugging.
884

DBD::Mock::StatementTrack::Iterator

886       This object can be used to iterate through the current set of
887       "DBD::Mock::StatementTrack" objects in the history by fetching the
888       "mock_all_history_iterator" attribute from a database handle. This
889       object is very simple and is meant to be a convenience to make writing
890       long test script easier. Aside from the constructor ("new") this object
891       has the following methods.
892
893       next()
894           Calling "next" will return the next "DBD::Mock::StatementTrack"
895           object in the history. If there are no more
896           "DBD::Mock::StatementTrack" objects available, then this method
897           will return false.
898
899       reset()
900           This will reset the internal pointer to the beginning of the
901           statement history.
902

DBD::Mock::Session

904       The "DBD::Mock::Session" object is an alternate means of specifying the
905       SQL statements and result sets for "DBD::Mock". The idea is that you
906       can specify a complete 'session' of usage, which will be verified
907       through "DBD::Mock". Here is an example:
908
909           my $session = DBD::Mock::Session->new('my_session' => (
910               {
911                   statement => "SELECT foo FROM bar", # as a string
912                   results   => [[ 'foo' ], [ 'baz' ]]
913               },
914               {
915                   statement => qr/UPDATE bar SET foo \= \'bar\'/, # as a reg-exp
916                   results   => [[]]
917               },
918               {
919                   statement => sub {  # as a CODE ref
920                           my ($SQL, $state) = @_;
921                           return $SQL eq "SELECT foo FROM bar";
922                           },
923                   results   => [[ 'foo' ], [ 'bar' ]]
924               },
925               {
926                   # with bound parameters
927                   statement    => "SELECT foo FROM bar WHERE baz = ? AND borg = ?",
928                   # check exact bound param value,
929                   # then check it against regexp
930                   bound_params => [ 10, qr/\d+/ ],
931                   results      => [[ 'foo' ], [ 'baz' ]]
932               }
933           ));
934
935       As you can see, a session is essentially made up a list of HASH
936       references we call 'states'. Each state has a "statement" and a set of
937       "results". If "DBD::Mock" finds a session in the "mock_session"
938       attribute, then it will pass the current $dbh and SQL statement to that
939       "DBD::Mock::Session". The SQL statement will be checked against the
940       "statement" field in the current state. If it passes, then the
941       "results" of the current state will get fed to "DBD::Mock" through the
942       "mock_add_resultset" attribute. We then advance to the next state in
943       the session, and wait for the next call through "DBD::Mock".  If at any
944       time the SQL statement does not match the current state's "statement",
945       or the session runs out of available states, an error will be raised
946       (and propagated through the normal DBI error handling based on your
947       values for "RaiseError" and "PrintError").
948
949       As can be seen in the session element, bound parameters can also be
950       supplied and tested. In this statement, the SQL is compared, then when
951       the statement is executed, the bound parameters are also checked. The
952       bound parameters must match in both number of parameters and the
953       parameters themselves, or an error will be raised.
954
955       As can also be seen in the example above, "statement" fields can come
956       in many forms. The simplest is a string, which will be compared using
957       "eq" against the currently running statement. The next is a reg-exp
958       reference, this too will get compared against the currently running
959       statement. The last option is a CODE ref, this is sort of a catch-all
960       to allow for a wide range of SQL comparison approaches (including using
961       modules like SQL::Statement or SQL::Parser for detailed functional
962       comparisons). The first argument to the CODE ref will be the currently
963       active SQL statement to compare against, the second argument is a
964       reference to the current state HASH (in case you need to alter the
965       results, or store extra information). The CODE is evaluated in boolean
966       context and throws and exception if it is false.
967
968       "new ($session_name, @session_states)"
969           A $session_name can be optionally be specified, along with at least
970           one @session_states. If you don't specify a $session_name, then a
971           default one will be created for you. The @session_states must all
972           be HASH references as well, if this conditions fail, an exception
973           will be thrown.
974
975       "verify_statement ($dbh, $SQL)"
976           This will check the $SQL against the current state's "statement"
977           value, and if it passes will add the current state's "results" to
978           the $dbh. If for some reason the "statement" value is bad, not of
979           the prescribed type, an exception is thrown. See above for more
980           details.
981
982       "verify_bound_params ($dbh, $params)"
983           If the "bound_params" slot is available in the current state, this
984           will check the $params against the current state's "bound_params"
985           value. Both number of parameters and the parameters themselves must
986           match, or an error will be raised.
987
988       "reset"
989           Calling this method will reset the state of the session object so
990           that it can be reused.
991

EXPERIMENTAL FUNCTIONALITY

993       All functionality listed here is highly experimental and should be used
994       with great caution (if at all).
995
996       Connection Callbacks
997           This feature allows you to define callbacks that get executed when
998           "DBI->connect" is called.
999
1000           To set a series of callbacks you use the
1001           "DBD::Mock::dr::set_connect_callbacks" function
1002
1003               use DBD::Mock::dr;
1004
1005               DBD::Mock::dr::set_connect_callbacks( sub {
1006                   my ( $dbh, $dsn, $user, $password, $attributes ) = @_;
1007
1008                   $dbh->{mock_add_resultset} = {
1009                       sql => 'SELECT foo FROM bar',
1010                       results => [[ 'foo' ], [ 10 ]]
1011                   };
1012               } );
1013
1014           To set more than one callback to you can simply add extra callbacks
1015           to your call to "DBD::Mock::dr::set_connect_callbacks"
1016
1017               DBD::Mock::dr::set_connect_callbacks(
1018                   sub {
1019                       my ( $dbh, $dsn, $user, $password, $attributes ) = @_;
1020
1021                       $dbh->{mock_add_resultset} = {
1022                           sql => 'SELECT foo FROM bar',
1023                           results => [[ 'foo' ], [ 10 ]]
1024                       };
1025                   },
1026
1027                   sub {
1028                       my ( $dbh, $dsn, $user, $password, $attributes ) = @_;
1029
1030                       $dbh->{mock_add_resultset} = {
1031                           sql => 'SELECT foo FROM bar',
1032                           results => [[ 'foo' ], [ 10 ]]
1033                       };
1034                   }
1035               );
1036
1037           Or you can extend the existing set of callbacks with the
1038           "DBD::Mock::dr::add_connect_callbacks" function
1039
1040               DBD::Mock::dr::add_connect_callbacks( sub {
1041                   ( my $dbh, $dsn, $user, $password, $attributes ) = @_;
1042
1043                   $dbh->{mock_add_resultset} = {
1044                       sql => 'SELECT bar FROM foo',
1045                       results => [[ 'bar' ], [ 50 ]]
1046                   };
1047               } );
1048
1049       table_info
1050           This feature adds support for DBI's "table_info" method ( Note this
1051           functionality is unstable when used with DBI version 1.634 and
1052           below).
1053
1054           To mock the table info for a search of the "testSchema" database
1055           schema you would use the following:
1056
1057               $dbh->{mock_add_table_info} = {
1058                   cataloge   => undef,
1059                   schema     => 'testSchema',
1060                   table      => undef,
1061                   type       => undef,
1062                   table_info => [
1063                       [ 'TABLE_CAT', 'TABLE_SCHEM', 'TABLE_NAME', 'TABLE_TYPE', 'REMARKS' ],
1064                       [ undef,       'testSchema',  'foo',        'TABLE',      undef     ],
1065                       [ undef,       'testSchema',  'bar',        'VIEW',       undef     ],
1066                   ],
1067               };
1068
1069           The "cataloge", "schema", "table" and "type" parameters need to
1070           explicitly match what you expect table_info to be called with
1071           (note: "table_info" treats "undef" and '' the same).
1072
1073           Similar to the "mock_results_sets", the "table_info" parameter's
1074           first entry is an arrayref of column names, and the rest are the
1075           values of the rows returned (one arrayref per row).
1076
1077           If you need to cover listing schemas then you'd use:
1078
1079               $dbh->{mock_add_table_info} = {
1080                   schema     => '%',
1081                   table_info => [
1082                       [ 'TABLE_CAT', 'TABLE_SCHEM',  'TABLE_NAME', 'TABLE_TYPE', 'REMARKS' ],
1083                       [ undef,       'testSchema',   undef,        undef,        undef     ],
1084                       [ undef,       'testSchema_2', undef,        undef,        undef     ],
1085                   ],
1086               }
1087
1088           To clear the current mocked table info set the database handle's
1089           "mock_clear_table_info" attribute to 1
1090
1091               $dbh->{mock_clear_table_info} = 1;
1092
1093       Result Set Callbacks
1094           If you need your result sets to be more dynamic (e.g. if they need
1095           to return different results based upon bound parameters) then you
1096           can use a callback.
1097
1098               $dbh->{mock_add_resultset} = {
1099                   sql => 'SELECT a FROM b WHERE c = ?',
1100                   callback => sub {
1101                       my @bound_params = @_;
1102
1103                       my %result = (
1104                           fields => [ "a" ],
1105                           rows => [[ 1] ]
1106                       );
1107
1108                       if ($bound_params[0] == 1) {
1109                           $result{rows} = [ [32] ];
1110                       } elsif ($bound_params[0] == 2) {
1111                           $result{rows} = [ [43] ];
1112                       }
1113
1114                       return %result;
1115                   },
1116               };
1117
1118               my $sth = $dbh->prepare('SELECT a FROM b WHERE c = ?');
1119
1120               my $rows = $sth->execute(1);
1121               my ($result) = $sth->fetchrow_array();  # $result will be 32
1122
1123               $rows = $sth->execute(2);
1124               ($result) = $sth->fetchrow_array();  # $result this time will be 43
1125
1126               $rows = $sth->execute(33); # $results this time will be 1
1127
1128               ($result) = $sth->fetchrow_array();
1129
1130           The callback needs to return a hash with a "rows" key that is an
1131           array ref of arrays containing the values to return as the answer
1132           to the query. In addition a "fields" key can also be returned with
1133           an array ref of field names. If a "fields" key isn't present in the
1134           returned the hash then the fields will be taken from the
1135           "mock_add_resultset"'s "results" parameter.
1136
1137               $dbh->{mock_add_resultset} = {
1138                   sql => 'SELECT x FROM y WHERE z = ?',
1139                   results => [ ["x"] ],
1140                   callback => sub {
1141                       my @bound_params = @_;
1142
1143                       my %result = ( rows => [[ 1] ] );
1144
1145                       if ($bound_params[0] == 1) {
1146                           $result{rows} = [ [32] ];
1147                       } elsif ($bound_params[0] == 2) {
1148                           $result{rows} = [ [43] ];
1149                       }
1150
1151                       return %result;
1152                   },
1153               };
1154
1155               my $sth = $dbh->prepare('SELECT x FROM y WHERE z = ?');
1156
1157               my $rows = $sth->execute(1);
1158               my ($result) = $sth->fetchrow_array();  # $result will be 32
1159
1160               $rows = $sth->execute(2);
1161               ($result) = $sth->fetchrow_array();  # $result will be 43
1162
1163               $rows = $sth->execute(33);
1164               ($result) = $sth->fetchrow_array();  # $result will be 1
1165
1166           By default result sets which only define their field names in their
1167           callback return values will have a "NUM_OF_FIELDS" property of 0
1168           until after the statement has actually been executed. This is to
1169           make sure that "DBD::Mock" stays compatible with previous versions.
1170           If you need the "NUM_OF_FIELDS" property to be undef in this
1171           situation then set the $DBD::Mock::DefaultFieldsToUndef flag to 1.
1172
1173           If you're mocking an INSERT statement with a callback and you want
1174           to explicitly set the database's "last_insert_id" value then you
1175           can use the "last_insert_id" key in the result set.  If you don't
1176           specify a "last_insert_id" then the standard "DBD::Mock" logic for
1177           generating an value for the last inserted item will be followed.
1178           This will allow you to mock MySQL/MariaDB INSERT queries that use
1179           "ON DUPLICATE KEY UPDATE" logic to set the "last_insert_id".
1180
1181               $dbh->{mock_add_resultset} = {
1182                   sql => 'INSERT INTO y ( x ) VALUES ( ? ) ON DUPLICATE KEY UPDATE id = LAST_INSERT_ID( id )',
1183                   callback => sub {
1184                       my @bound_params = @_;
1185
1186                       my %result = (
1187                           fields => [],
1188                           rows => [],
1189                           last_insert_id => 99,
1190                       );
1191
1192                       return %result;
1193                   },
1194               };
1195
1196       Result Set Custom Attributes
1197           If you're mocking a database driver that has it's own custom
1198           attributes attached to its statement handles then you can use the
1199           result sets "prepare_attributes" and "execute_attributes" options.
1200
1201           The "prepare_attributes" option takes a hashref that maps statement
1202           handle attribute names to their values.  The attributes are set at
1203           the point that the statement is prepared.
1204
1205               $dbh->{mock_add_resultset} = {
1206                   sql => 'SELECT foo FROM bar',
1207                   prepare_attributes => {
1208                       sqlite_unprepared_statements => '   ',
1209                   },
1210                   results => [[ 'foo' ], [ 10 ]]
1211               };
1212
1213           The "execute_attributes" option also takes a hashref that maps
1214           statement handle attribute names to their values, however these
1215           will only be set when the statement is executed.
1216
1217               $dbh->{mock_add_resultset} = {
1218                   sql => 'SELECT foo FROM bar',
1219                   execute_attributes => {
1220                       syb_result_type => 1,
1221                   },
1222                   results => [[ 'foo' ], [ 10 ]]
1223               };
1224
1225           If an attribute is also present in the "prepare_attributes" option
1226           then the "prepare_attributes" version will take precedence up to
1227           the point the statement handle is executed, at which point the
1228           "execute_attributes" version will take precedence.
1229
1230           It is also possible to set "execute_attributes" from a result set's
1231           callback by returning them under the "execute_attributes" key in
1232           your callback's response.
1233
1234               $dbh->{mock_add_resultset} = {
1235                   sql => 'SELECT baz FROM qux',
1236                   callback => sub {
1237                       my @bound_params = @_;
1238
1239                       my %result = (
1240                           fields => [ 'baz'],
1241                           rows => [],
1242                           execute_attributes => {
1243                               foo => 'bar'
1244                           },
1245                       );
1246
1247                       return %result;
1248                   }
1249               };
1250
1251           If a result set has an "execute_attributes" option and a callback
1252           that also returns an "execute_attributes" key then the callback's
1253           "execute_attributes" value will take precedence.
1254

BUGS

1256       Odd $dbh attribute behavior
1257           When writing the test suite I encountered some odd behavior with
1258           some $dbh attributes. I still need to get deeper into how DBD's
1259           work to understand what it is that is actually doing wrong.
1260

TO DO

1262       Make DBD specific handlers
1263           Each DBD has its own quirks and issues, it would be nice to be able
1264           to handle those issues with "DBD::Mock" in some way. I have an
1265           number of ideas already, but little time to sit down and really
1266           flesh them out. If you have any suggestions or thoughts, feel free
1267           to email me with them.
1268
1269       Enhance the "DBD::Mock::StatementTrack" object
1270           I would like to have the "DBD::Mock::StatementTrack" object handle
1271           more of the "mock_*" attributes. This would encapsulate much of the
1272           "mock_*" behavior in one place, which would be a good thing.
1273

SEE ALSO

1275       DBI
1276
1277       DBD::NullP, which provided a good starting point
1278
1279       Test::MockObject, which provided the approach
1280
1281       Test::MockObject article -
1282       <http://www.perl.com/pub/a/2002/07/10/tmo.html>
1283
1284       Perl Code Kata: Testing Databases -
1285       <http://www.perl.com/pub/a/2005/02/10/database_kata.html>
1286

ACKNOWLEDGEMENTS

1288       Thanks to Ryan Gerry for his patch in RT #26604.
1289       Thanks to Marc Beyer for his patch in RT #16951.
1290       Thanks to Justin DeVuyst for the mock_connect_fail idea.
1291       Thanks to Thilo Planz for the code for "bind_param_inout".
1292       Thanks to Shlomi Fish for help tracking down RT Bug #11515.
1293       Thanks to Collin Winter for the patch to fix the begin_work(), commit()
1294       and rollback() methods.
1295       Thanks to Andrew McHarg <amcharg@acm.org> for fetchall_hashref(),
1296       fetchrow_hashref() and selectcol_arrayref() methods and tests.
1297       Thanks to Andrew W. Gibbs for the "mock_last_insert_ids" patch and
1298       test.
1299       Thanks to Chas Owens for patch and test for the "mock_can_prepare",
1300       "mock_can_execute", and "mock_can_fetch" features.
1301       Thanks to Tomas Zemresfor the unit test in RT #71438.
1302       Thanks to Bernhard Graf for multiple patches fixing a range of issues
1303       and adding a new One Shot Failure feature to "mock_add_resultset".
1304       Thanks to Erik Huelsmann for testing the new result set custom
1305       attributes feature.
1306
1308       Copyright (C) 2004 Chris Winters <chris@cwinters.com>
1309
1310       Copyright (C) 2004-2007 Stevan Little <stevan@iinteractive.com>
1311
1312       Copyright (C) 2007 Rob Kinyon <rob.kinyon@gmail.com>
1313
1314       Copyright (C) 2011 Mariano Wahlmann <dichoso  _at_ gmail.com>
1315
1316       Copyright (C) 2019 Jason Cooper <JLCOOPER@cpan.org>
1317
1318       This library is free software; you can redistribute it and/or modify it
1319       under the same terms as Perl itself.
1320

AUTHORS

1322       Chris Winters <chris@cwinters.com>
1323
1324       Stevan Little <stevan@iinteractive.com>
1325
1326       Rob Kinyon <rob.kinyon@gmail.com>
1327
1328       Mariano Wahlmann <dichoso _at_ gmail.com>
1329
1330       Jason Cooper <JLCOOPER@cpan.org>
1331
1332
1333
1334perl v5.38.0                      2023-07-20                    DBD::Mock(3pm)
Impressum