Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Perl 为存储过程指定输出值_Perl_Testing - Fatal编程技术网

Perl 为存储过程指定输出值

Perl 为存储过程指定输出值,perl,testing,Perl,Testing,我正在尝试使用来测试使用数据库的代码。到目前为止,普通的SQL查询工作得很好,但是我对如何测试调用存储过程的代码有些茫然。使用DBD::Mock::Session->new构造函数的bound_params键,我可以指定输入参数,但似乎找不到一种方法来设置使用DBI::StatementHandle::bind_param_inout()绑定的参数的模拟结果 要提供将要测试的代码的示例,请查看以下内容: use DBI; my $dbh = DBI->connect('dbi:Mock',

我正在尝试使用来测试使用数据库的代码。到目前为止,普通的SQL查询工作得很好,但是我对如何测试调用存储过程的代码有些茫然。使用
DBD::Mock::Session->new
构造函数的
bound_params
键,我可以指定输入参数,但似乎找不到一种方法来设置使用
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";
现在,我想用
arg2
参数的
'frobnication'
为DB种子,这样当执行上述代码时,
$arg2
变量包含这个字符串,并且输出是

arg2的OUTPUTVALUE=泡沫化

您可以使用覆盖此sub

您可以像这样修改模拟对象并创建新的模拟子对象

$mocked_dbd->mock( 'bind_param_inout',&mocked_bind_param_inout );
在我看来,这种方法在这里被模仿了:

也许这会奏效:

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);

这就是我最后要做的。基本上,主要工作是覆盖
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";

对不起,你把我弄丢了。。。如果在第一个代码示例中,
mock\u dbd
是一个数据库句柄,那么我在
dbd::mock
文档中没有看到任何
mock
方法,那么您在这里指的是什么?第二个代码块将如何帮助我?我没有检索结果集,不涉及SQL。我只是用参数调用一个存储过程,其中一些是我想要为其设定值的输出参数。DBD::Mock从其父级继承了Mock方法。代码部分:我检查了st.pm中的代码和测试文件,它认为它可以工作。很抱歉,此模块未安装在此处,我无法试用。这很有效,谢谢,但是我确实遇到了
0
值的问题,尽管如此,我不得不将
shift
语句更改为破坏性较小的变体<代码>$$val=shift@values因为移位
0
返回
0
,因此子例程终止。裁判: