samedi 31 octobre 2015

How to deploy a test database for DBIx Class

I have Mojolicious app with a test suite using Test::Class::Moose. Using DBIx::Class to interact with my database, is there a way to setup an in-memory database that I can add fixture data to?

I'd like to use an in memory database because it'll mean that the application will have less setup configuration. I do know how to setup an actual SQLite database for testing but managing that for testing along with a mySQL database for production doesn't sound like easy management (eg "oh no, forgot to rebuild the testing database").

Loading data from fixtures seems ideal, that way you have more control over what is actually in the database. Example, you find a bug with a row that contains certain data, add a row like that to your fixture file and test until successful.

Now how to actually set up an in-memory database using DBIx? :)

Right now this is how I'm building the schema for my Test::Class::Moose suite:

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

Where my config specifies dbi:SQLite:dbname=:memory: as the database dsn.

When running the test suite, the tables don't seem to be loaded, as I get errors stating the table does not exist, eg Can't locate object method "id" via package "no such table: cats"

Is there some extra setup that I'm not doing when wanting to deploy to an in-memory database?

Thanks

Aucun commentaire:

Enregistrer un commentaire