DBD-Mock
view release on metacpan or search on metacpan
SQL statement will be checked against the `statement` field in the current
state. If it passes, then the `results` of the current state will get fed to
`DBD::Mock` through the `mock_add_resultset` attribute. We then advance to
the next state in the session, and wait for the next call through `DBD::Mock`.
If at any time the SQL statement does not match the current state's
`statement`, or the session runs out of available states, an error will be
raised (and propagated through the normal DBI error handling based on your
values for `RaiseError` and `PrintError`).
As can be seen in the session element, bound parameters can also be supplied
and tested. In this statement, the SQL is compared, then when the statement is
executed, the bound parameters are also checked. The bound parameters must
match in both number of parameters and the parameters themselves, or an error
will be raised.
As can also be seen in the example above, `statement` fields can come in many
forms. The simplest is a string, which will be compared using `eq` against the
currently running statement. The next is a reg-exp reference, this too will get
compared against the currently running statement. The last option is a CODE
ref, this is sort of a catch-all to allow for a wide range of SQL comparison
approaches (including using modules like [SQL::Statement](https://metacpan.org/pod/SQL::Statement) or [SQL::Parser](https://metacpan.org/pod/SQL::Parser)
for detailed functional comparisons). The first argument to the CODE ref will
be the currently active SQL statement to compare against, the second argument
is a reference to the current state HASH (in case you need to alter the
results, or store extra information). The CODE is evaluated in boolean context
and throws and exception if it is false.
- **`new ($session_name, @session_states)`**
A `$session_name` can be optionally be specified, along with at least one
`@session_states`. If you don't specify a `$session_name`, then a default one
will be created for you. The `@session_states` must all be HASH references as
well, if this conditions fail, an exception will be thrown.
- **`verify_statement ($dbh, $SQL)`**
This will check the `$SQL` against the current state's `statement` value, and
if it passes will add the current state's `results` to the `$dbh`. If for
some reason the `statement` value is bad, not of the prescribed type, an
exception is thrown. See above for more details.
- **`verify_bound_params ($dbh, $params)`**
If the `bound_params` slot is available in the current state, this will check
the `$params` against the current state's `bound_params` value. Both number
of parameters and the parameters themselves must match, or an error will be
raised.
- **`reset`**
Calling this method will reset the state of the session object so that it can
be reused.
# EXPERIMENTAL FUNCTIONALITY
All functionality listed here is highly experimental and should be used with
great caution (if at all).
- Connection Callbacks
This feature allows you to define callbacks that get executed when
`DBI->connect` is called.
To set a series of callbacks you use the
`DBD::Mock::dr::set_connect_callbacks` function
use DBD::Mock::dr;
DBD::Mock::dr::set_connect_callbacks( sub {
my ( $dbh, $dsn, $user, $password, $attributes ) = @_;
$dbh->{mock_add_resultset} = {
sql => 'SELECT foo FROM bar',
results => [[ 'foo' ], [ 10 ]]
};
} );
To set more than one callback to you can simply add extra callbacks to your
call to `DBD::Mock::dr::set_connect_callbacks`
DBD::Mock::dr::set_connect_callbacks(
sub {
my ( $dbh, $dsn, $user, $password, $attributes ) = @_;
$dbh->{mock_add_resultset} = {
sql => 'SELECT foo FROM bar',
results => [[ 'foo' ], [ 10 ]]
};
},
sub {
my ( $dbh, $dsn, $user, $password, $attributes ) = @_;
$dbh->{mock_add_resultset} = {
sql => 'SELECT foo FROM bar',
results => [[ 'foo' ], [ 10 ]]
};
}
);
Or you can extend the existing set of callbacks with the
`DBD::Mock::dr::add_connect_callbacks` function
DBD::Mock::dr::add_connect_callbacks( sub {
( my $dbh, $dsn, $user, $password, $attributes ) = @_;
$dbh->{mock_add_resultset} = {
sql => 'SELECT bar FROM foo',
results => [[ 'bar' ], [ 50 ]]
};
} );
- table\_info
This feature adds support for DBI's `table_info` method (
_Note this functionality is unstable when used with DBI version 1.634 and below_).
To mock the table info for a search of the `testSchema` database schema you
would use the following:
$dbh->{mock_add_table_info} = {
cataloge => undef,
schema => 'testSchema',
table => undef,
type => undef,
table_info => [
[ 'TABLE_CAT', 'TABLE_SCHEM', 'TABLE_NAME', 'TABLE_TYPE', 'REMARKS' ],
[ undef, 'testSchema', 'foo', 'TABLE', undef ],
[ undef, 'testSchema', 'bar', 'VIEW', undef ],
],
};
The `cataloge`, `schema`, `table` and `type` parameters need to explicitly
match what you expect table\_info to be called with (note: `table_info` treats
`undef` and `''` the same).
Similar to the `mock_results_sets`, the `table_info` parameter's first entry
is an arrayref of column names, and the rest are the values of the rows
returned (one arrayref per row).
If you need to cover listing schemas then you'd use:
$dbh->{mock_add_table_info} = {
schema => '%',
table_info => [
[ 'TABLE_CAT', 'TABLE_SCHEM', 'TABLE_NAME', 'TABLE_TYPE', 'REMARKS' ],
[ undef, 'testSchema', undef, undef, undef ],
[ undef, 'testSchema_2', undef, undef, undef ],
],
}
To clear the current mocked table info set the database handle's
`mock_clear_table_info` attribute to `1`
$dbh->{mock_clear_table_info} = 1;
- Result Set Callbacks
If you need your result sets to be more dynamic (e.g. if they need to return
different results based upon bound parameters) then you can use a callback.
$dbh->{mock_add_resultset} = {
sql => 'SELECT a FROM b WHERE c = ?',
callback => sub {
( run in 1.580 second using v1.01-cache-2.11-cpan-39bf76dae61 )