Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 1007997
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 16, 20262026-05-16T08:42:08+00:00 2026-05-16T08:42:08+00:00

I’m trying to test some code in different situations (for different result sets). I’ve

  • 0

I’m trying to test some code in different situations (for different result sets). I’ve got the first test running well, but the next one is trying to reuse the first “table”.

My result sets:

my $usernames_many = [
      { username => '1234567' },
      { username => '2345678' },
   ];
my $usernames_empty = [
   ];

but now when I try these calls:

$mock_dbi->set_retval_scalar(MOCKDBI_WILDCARD, "SELECT username FROM location", $usernames_many);
is_deeply(find_multiple_registrations($mock_db, 15), [ '1234567', '2345678' ], "many entries");

$mock_dbi->set_retval_scalar(MOCKDBI_WILDCARD, "SELECT username FROM location", $usernames_empty);
is_deeply(find_multiple_registrations($mock_db, 15), [ ], "no entries");

The first test passes, but the second one results in:

not ok 3 - no entries
#   Failed test 'no entries'
#   at ./report_many_registrations_test.pl line 28.
#     Structures begin differing at:
#          $got->[0] = '1234567'
#     $expected->[0] = Does not exist

Which seems to indicate the first resultset was used again instead. How can I clean a resultset? Or reset the state in some other way?

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-16T08:42:09+00:00Added an answer on May 16, 2026 at 8:42 am

    The implementation of set_retval_scalar may at first appear discouraging:

    sub set_retval_scalar {
        my $self   = shift;                 # my blessed self
        my $type   = shift;                 # type number from --dbitest=TYPE
        my $sql    = shift;                 # SQL pattern for badness
    
        push @{ $scalar_retval{$type} },
         { "SQL" => $sql, "retval" => $_[0] };
    }
    

    The reason the first resultset appeared to be used again is successive calls to set_retval_scalar are cumulative. After the second call to set_retval_scalar, just before the second test, the internal bookkeeping for Test::MockDBI resembles

    [ # first resultset
      { SQL => "SELECT username ...",
        retval => [{ username => '1234567' }, ...]
      },
      # second resultset
      { SQL => "SELECT username ...",
        retval => []
      }
    ]
    

    Under the hood when your second test queries SELECT username ..., _force_retval_scalar in Test::MockDBI searches this data structure for the currently executing query and stops on the first hit it finds. Both resultsets are associated with the same query, so the second doesn’t have a chance to match.

    But there’s hope! Notice that set_retval_scalar copies only the outermost reference—a reference to an array that you control!

    Modify your test slightly:

    my @usernames_many = (
      { username => '1234567' },
      { username => '2345678' },
    );
    
    my @usernames_empty = ();
    
    my $usernames = [];
    $mock_dbi->set_retval_scalar(
      MOCKDBI_WILDCARD,
      "SELECT username FROM location",
      $usernames);
    

    With this fixture, you need only change the contents of @$usernames (that is, the array referred to by $usernames) to change the canned result of the query:

    @$usernames = @usernames_many;
    is_deeply(find_multiple_registrations($mock_db, 15),
              [ '1234567', '2345678' ],
              "many entries");
    
    @$usernames = @usernames_empty;
    is_deeply(find_multiple_registrations($mock_db, 15),
              [ ],
              "no entries");
    

    With these modifications, both tests pass.

    IMPORTANT: Always assign to @$usernames! You may be tempted to save a few keystrokes by writing

    $usernames = [];  # empty usernames
    is_deeply(find_multiple_registrations($mock_db, 15),
              [ ],
              "no entries");
    

    but this will cause your test to fail for nearly the same reason as the test from your question: the fixture will continue to have the same reference that you gave it in the call to set_retval_scalar. Doing it this way would be both incorrect and misleading, a nasty combination.


    For completeness, a full working example is below.

    #! /usr/bin/perl
    
    use warnings;
    use strict;
    
    BEGIN { push @ARGV, "--dbitest" }
    
    use Test::MockDBI qw/ :all /;
    use Test::More tests => 2;
    
    my @usernames_many = (
          { username => '1234567' },
          { username => '2345678' },
       );
    my @usernames_empty = ();
    
    my $usernames = [];
    
    my $mock_dbi = get_instance Test::MockDBI;
    my $mock_db = DBI->connect("dbi:SQLite:dbname=:memory:", "", "");
    $mock_db->{RaiseError} = 1;
    $mock_db->do(q{CREATE TABLE location (username char(10))});
    
    sub find_multiple_registrations {
      my($dbh,$limit) = @_;
      my $sth = $dbh->prepare("SELECT username FROM location");
      $sth->execute;
      [ map $_->{username} => @{ $sth->fetchall_arrayref } ];
    }
    
    $mock_dbi->set_retval_scalar(
      MOCKDBI_WILDCARD,
      "SELECT username FROM location",
      $usernames);
    
    @$usernames = @usernames_many;
    is_deeply(find_multiple_registrations($mock_db, 15),
              [ '1234567', '2345678' ],
              "many entries");
    
    @$usernames = ();
    is_deeply(find_multiple_registrations($mock_db, 15),
              [ ],
              "no entries");
    

    Output:

    1..2
    
    connect() 'CONNECT TO dbi:SQLite:dbname=:memory: AS  WITH '
    
    do() 'CREATE TABLE location (username char(10))'
    
    prepare() 'SELECT username FROM location'
    
    execute()
    
    fetchall_arrayref()
    ok 1 - many entries
    
    prepare() 'SELECT username FROM location'
    
    execute()
    
    fetchall_arrayref()
    ok 2 - no entries
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have a French site that I want to parse, but am running into
I am trying to understand how to use SyndicationItem to display feed which is
Basically, what I'm trying to create is a page of div tags, each has
link Im having trouble converting the html entites into html characters, (&# 8217;) i
I have just tried to save a simple *.rtf file with some websites and
I want to count how many characters a certain string has in PHP, but
For some reason, after submitting a string like this Jack’s Spindle from a text
I have a string like this: La Torre Eiffel paragonata all’Everest What PHP function
I've got a string that has curly quotes in it. I'd like to replace
I am trying to render a haml file in a javascript response like so:

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.