【问题标题】:How to deploy a test database for DBIx Class如何为 DBIx 类部署测试数据库
【发布时间】:2016-01-31 19:53:05
【问题描述】:

我有一个 Mojolicious 应用程序和一个使用 Test::Class::Moose 的测试套件。使用 DBIx::Class 与我的数据库交互,有没有办法设置一个内存数据库,我可以添加夹具数据?

我想使用内存数据库,因为这意味着应用程序的设置配置更少。我确实知道如何设置一个实际的 SQLite 数据库进行测试,但管理该数据库以用于测试以及用于生产的 mySQL 数据库听起来并不容易管理(例如“哦,不,忘记重建测试数据库”)。

从固定装置加载数据似乎很理想,这样您就可以更好地控制数据库中的实际内容。例如,您发现一行包含某些数据的错误,将这样的一行添加到您的夹具文件中并测试直到成功。

现在如何使用 DBIx 实际设置内存数据库? :)

现在这就是我为我的 Test::Class::Moose 套件构建架构的方式:

has cats => (
    is => 'ro',
    isa => 'Test::Mojo::Cats',
    default => sub { return Test::Mojo::Cats->new(); }
);

has schema => (
    is => 'ro',
    lazy => 1,
    builder => '_build_schema_and_populate',
);

sub _build_schema_and_populate {
    my $test = shift;
    my $config = $test->cats->app->config();
    my $schema = Cat::Database::Schema->connect(
        $config->{db_dsn},
        $config->{db_user},
        $config->{db_pass},
        {
            HandleError => DBIx::Error->HandleError,
            unsafe => 1
        }
    );

    require DBIx::Class::DeploymentHandler;
    my $dh = DBIx::Class::DeploymentHandler->new({
        schema  => $schema,
        sql_translator_args => { add_drop_table => 0 },
        schema_version => 3,
    });
    $dh->prepare_install;
    $dh->install;

    my $json = read_file $config->{fixture_file};
    my $fixtures = JSON::decode_json($json);

    $schema->resultset($_)->populate($fixtures->{$_}) for keys %{$fixtures};

    return $schema;
}

我的配置将 dbi:SQLite:dbname=:memory: 指定为数据库 dsn。

运行测试套件时,似乎没有加载表,因为我收到错误提示表不存在,例如Can't locate object method "id" via package "no such table: cats"

当我想部署到内存数据库时,是否有一些额外的设置我没有做?

谢谢

PS:

在单个脚本中执行以下工作,我不知道我是否正在做一些 Test::Class::Moose 或 Mojo 不喜欢上面的事情

#!/usr/bin/perl

use Cats::Database::Schema;
use File::Slurp;
use JSON;
use Data::Dumper;

my $schema = Cats::Database::Schema->connect(
    'dbi:SQLite:dbname=:memory:', '', ''
);

my $json = read_file('../t/fixtures.json');
my $fixtures = JSON::decode_json($json);

$schema->deploy();
$schema->resultset($_)->populate($fixtures->{$_}) for keys %{$fixtures};

# returns fixture data fine
# warn Dumper($schema->resultset('User')->search({}));

【问题讨论】:

  • 请注意,DBIx 是一个名称空间,其中 DBIx::Class 只是模块的一种分布。 DBIx::Class 的缩写是 DBIC。

标签: perl testing automated-tests dbix-class test-class


【解决方案1】:

我相信我想通了

我在应用程序中使用 DBIx 模式的方式是在所有子控制器都继承的基本控制器中实例化它。无论我如何在 Test::Class::Moose 对象中构建和填充内存数据库,它都不会使用那里指定的实例,而是使用基本控制器中指定的实例。

解决方案是将架构构造上移一级(从控制器到应用程序根)作为属性,允许我在 Test Mojo 中覆盖它以使用内存数据库。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-05
    • 1970-01-01
    • 1970-01-01
    • 2013-09-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多