4

DBD :: Mockを使用して、データベースを使用するコードをテストしようとしています。これまでのところ、通常のSQLクエリは問題なく機能しますが、ストアドプロシージャを呼び出すコードをテストする方法については少し戸惑っています。bound_paramsコンストラクターのキーを使用してDBD::Mock::Session->new入力パラメーターを指定することはできますが、を使用してバインドされたパラメーターの模擬結果を設定する方法が見つからないようですDBI::StatementHandle::bind_param_inout()

テストされるコードの例を提供するには、以下を参照してください。

use DBI;
my $dbh = DBI->connect('dbi:Mock', '', '', { RaiseError => 1, PrintError => 1 });
my $sth = $dbh->prepare(q{
BEGIN
  some_stored_proc(i_arg1 => :arg1, o_arg2 => :arg2);
END;
});
my ($arg1, $arg2) = ('foo', 'bar');
$sth->bind_param(':arg1', $arg1);
$sth->bind_param_inout(':arg2', \$arg2, 200);
$sth->execute();
print STDERR "OUTPUT VALUE OF arg2 = $arg2\n";

ここで、上記のコードが実行されたときに変数にこの文字列が含まれ、出力が次のようになるよう'frobnication'に、パラメーターのDBをシードします。arg2$arg2

arg2の出力値=フロブニケーション

4

2 に答える 2

1

これが私がやったことです。基本的に、主な作業はDBD::Mock::st::bind_param_inoutメソッドのオーバーライドになります。

use DBI;
use DBD::Mock;
use DBD::Mock::st;
use Carp;

# array of values to be bound on each invocation
my @values = qw/frobnication/;
# dummy variable to trick DBD::Mock into thinking it got the same reference for
# bind_param_inout and bound_params (the former is usually not in the control of
# the testing code, hence this hack).
my $dummy = undef;
# keep reference to the original bind_param_inout method
my $bind_param_inout_orig = \&DBD::Mock::st::bind_param_inout;
# override with our mocked version that assigns a value to the reference.
# notice that it does so at the bind_param_inout call, *NOT* the execute call!
local *DBD::Mock::st::bind_param_inout = sub {
  my ($self, $param_num, $val, $size) = (shift, shift, shift, shift);
  $bind_param_inout_orig->($self, $param_num, \$dummy, $size, @_);
  $$val = shift @values or Carp::confess '@values array exhausted!';
};

# set up the mock session
my $dbh = DBI->connect('dbi:Mock:', '', '',
  { RaiseError => 1, PrintError => 1 });
$dbh->{mock_session} = DBD::Mock::Session->new('foo_session' => (
  {
    statement => qr/BEGIN\n\s*some_stored_proc/,
    results => [],
    bound_params => ['foo', \$dummy]
  }));

# this is the code to be tested

my $sth = $dbh->prepare(q{
BEGIN
  some_stored_proc(i_arg1 => :arg1, o_arg2 => :arg2);
END;
});
my ($arg1, $arg2) = ('foo', 'bar');
$sth->bind_param(':arg1', $arg1);
$sth->bind_param_inout(':arg2', \$arg2, 200);
$sth->execute();
print STDERR "OUTPUT VALUE OF arg2 = $arg2\n";
于 2013-04-17T12:34:43.157 に答える
0

Sub :: Overrideを使用 して、このサブをオーバーライドできます。

このようにモックオブジェクトを変更して、新しいモックサブを作成できます。

$mocked_dbd->mock( 'bind_param_inout',&mocked_bind_param_inout );

このメソッドはここでモックされているように見えます:http://cpansearch.perl.org/src/DICHI/DBD-Mock-1.45/lib/DBD/Mock/st.pm

多分これはうまくいくでしょう:

my @rs_foo = (
    [ 'this', 'that' ],
    [ 'this_one', 'that_one' ],
    [ 'this_two', 'that_two' ],
);
# the first one ordered
$dbh->{mock_add_resultset} = [ @rs_foo ];

use Data::Dumper;
my $mocked_records = $sth->{mock_records};
print Dumper($mock_records);
于 2013-03-04T13:27:58.620 に答える