perl 单元测试(Test::Spec)有什么问题

问题描述 投票:0回答:1

请帮我对该功能进行单元测试

func_for_test
。 我不明白如何模拟
get_dbh
函数(我使用 Test::Spec)。

ModuleForTests.pm
-----------------

use ModuleMysql;

my $dbh = get_dbh();

sub **func_for_test** {

    my $sql = "DELETE ...";
    $dbh->prepare($sql);
    ...
}
ModuleMysql.pm
-----------------

sub get_dbh {

    state $dbh = DBI->connect ...

    return $dbh;
}

我尝试了 DBD::Mock,但没有帮助。

$drh = DBI->install_driver( 'Mock' );
$drh->{mock_connect_fail} = 0;
$dbh = DBI->connect( 'DBI:Mock:', '', '' );

我也尝试过,但没有帮助 - 错误 Test::Spec;

my $dbh;
BEGIN {
   $dbh = mock();
   ModuleForTests->stubs(get_dbh => $dbh);
}
perl testing mocking
1个回答
1
投票

使用 Test::Spec 迫使您以不同的方式编写代码(许多人认为这是正确的方式)。

如果你想使用 Test::Spec,最好对你的类使用面向对象的设计。 ModuleForTest 中填充的 Lexical

$dbh
模拟起来很复杂,最好将数据库句柄存储在对象属性中。但它是 Perl,一切皆有可能。

#!/usr/bin/perl
use warnings;
use strict;

use Test::Spec;
use Sub::Override;
use DBI;

use ModuleMysql;  # Needed here so we can override its get_dbh.

my $dbh;
BEGIN {
    $dbh = 'DBI'->connect('DBI:Mock:', "", "") or die $DBI::errstr;
}

my $override;
BEGIN {
    $override = 'Sub::Override'->new('ModuleMysql::get_dbh' => sub {
        return $dbh
    });
}

use ModuleForTest;

describe ModuleForTest => sub {
    it 'prepares delete' => sub {
        my $sth = ModuleForTest::func_for_test();
        my $history = $dbh->{mock_all_history};
        is($history->[0]->statement, 'DELETE ...');
    };
};

runtests();

需要

BEGIN
块,因为我们需要在ModuleMysql加载之后、MoudleForTest调用它之前的精确时刻重新定义get_dbh。

© www.soinside.com 2019 - 2024. All rights reserved.