1

我有一个 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({}));
4

1 回答 1

1

我相信我想通了

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

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

于 2015-10-31T15:57:08.583 回答