sirrobert has asked for the wisdom of the Perl Monks concerning the following question:

Hi all,

I've started the task of implementing a test suite for a largish code project. It's a CGI based project that uses a DB backend (mysql; in a LAMP environment). I've gotten a good start on the unit tests, but am now running into some trouble trying to deal with testing the database side of things. I've read quite a lot of material covering DBD::Mock and have successfully gotten things hooked up... but it seems to be returning data that's not helpful at all.

Am I missing something obvious? I've rtfm and a number of other online resources, but I just don't get it!

I've simplified the case to a simple case scenario. Looking at the "Test Execution" block below, obviously the data that's being returned in the 'SELECT' isn't what I asked for; I just wanted the "name" and "description." Also, they are not from the correct record (they are from the record where id=1 instead of id=3). Is DBD::Mock only good for getting the entire row's data or ...? Please help =)

########## FILES ########## ./t/mock_db_test.t ./t/sample_db_data_test.pm
############## Test execution ############## $ prove -v t/mock_db_test.t t/mock_db_test....ok 1 - baseline test # $VAR1 = [ # 1, # 'name1', # 'description1', # 'created_on1', # 'created_by1', # 'deleted1', # 'deleted_by1', # 'public1' # ]; 1..1 ok All tests successful. Files=1, Tests=1, 0 wallclock secs ( 0.03 cusr + 0.01 csys = 0.04 C +PU) $
################## ./t/mock_db_test.t ################## use Test::More qw(no_plan); use strict; use warnings; ### Just a blank test so this sample runs. ok(1,'baseline test'); ### Load DBI and create a handle. use DBI; my $dbh = DBI->connect('DBI:Mock:', '', ''); ### Load the sample data set into memory and add it as a resultset to +the ### mock db driver. use t::sample_db_data_test; $dbh->{'mock_add_resultset'} = \@t::sample_db_data_test::Accounts; ### Try to get just the name and description. my $sth = $dbh->prepare('SELECT name, description FROM Accounts WHERE +id=?'); if ($sth->execute(3)) { ### Successful query. my @results = $sth->fetchrow_array; use Data::Dumper; diag(Dumper(\@results)); } else { ### Failure... diag('Some weird error: ' . $sth->errstr); }
########################## ./t/sample_db_data_test.pm ########################## package t::sample_db_data_test; our @Accounts = ( ['id', 'name', 'description', 'created_on', 'created_by','deleted' +, 'deleted_by', 'public'], [ 1, 'name1','description1','created_on1','created_by1','deleted +1','deleted_by1','public1'], [ 2, 'name2','description2','created_on2','created_by2','deleted +2','deleted_by2','public2'], [ 3, 'name3','description3','created_on3','created_by3','deleted +3','deleted_by3','public3'], ); 1;

Replies are listed 'Best First'.
Re: DBD::Mock -- Giving back wrong data and wrong *amounts* of data
by andreas1234567 (Vicar) on Aug 20, 2009 at 18:53 UTC
    mock_add_resultset used with an array ref will return the given resultset regardless of what the sql query is. The documentation contains an example of how to make it return a particular resultset for a given query (see the sql_and_resultset option). Note that the sql can be anything, it does not have to be valid SQL. E.g. like this Update: Added code sample.
    --
    No matter how great and destructive your problems may seem now, remember, you've probably only seen the tip of them. [1]

      Ok, I see... I'm doing this testing within a framework that handles much of the SQL behind the scenes. I'll try to capture some of the queries being produced and associate them with good records.

      Is there a better approach to it than that?

        Is there a better approach to it than that?
        I would start by asking myself what is it I want to test? Write a test strategy, and take it on from there. Then break it down to individual tests e.g.
        • Does the application behave as I expect when the database is unavailable?
        • Does the application behave as I expect when the database returns unexpected results (e.g. no data, wrong charset, wrong number of columns, wrong data types, ..)?
        • Does the application behave as I expect in a foreign environment (e.g. on a different OS)?
        • ..

        Suggested reading: Perl Testing.

        You may also want to take a look at Test::MockDBI (Disclaimer: I one filed a patch to the given module and ended up as its' co-maintainer).

        Best of luck.

        --
        No matter how great and destructive your problems may seem now, remember, you've probably only seen the tip of them. [1]