NAME
DBIx::MoCo::Fixture - A fixture for testing model components of DBIx::MoCo
SYNOPSIS
## fixtures/entry.yml
model: My::Bookmark::Entry
records:
first:
id: 1
title: Hatena Bookmark
url: http://b.hatena.ne.jp/
second:
id: 2
title: Yahoo
url: http://www.yahoo.co.jp/
## t/entry.t
use DBIx::MoCo::Fixture;
use My::Bookmark::Entry;
use Test::More tests => 2;
my $f = fixtures(qw/entry/);
is My::Bookmark::Entry->retrieve(1)->title, $f->{entry}->{first}->{title};
is My::Bookmark::Entry->retrieve(2)->title, $f->{entry}->{second}->{title};
DESCRIPTION
A fixture loader for DBIx::MoCo. See DBIx::MoCo::Manual::Testing for more details.
METHODS
fixtures
my $f = fixtures(qw/entry bookmark/, { yaml_dir => "../fixtures" })
Automatically loads ../fixtures/entry.yml and ../fixtures/bookmark.yml to the database.
NOTE: All records for the specified model will be once removed when <fixtures()> called. Do not use fixtures when your model is connected to the production database.
More Details on How to Use DBIx::MoCo::Fixture
Testing with Fixtures
To test your model classes efficiently and strictly, you should use real data which will be used in your production environment. DBIx::MoCo has Rails-like feature for testing, that is, fixtures, and it helps you to automatically set up test data into database.
Tables and model classes
Here you're going to perform testing for the tables and model classes below:
Tables:
CREATE TABLE user (
id INTEGER PRIMARY KEY,
name varchar(255)
);
CREATE TABLE entry (
id INTEGER PRIMARY KEY,
user_id INTEGER,
title varchar(255),
body text
)
Model classes:
package Blog::MoCo::User;
use strict;
use warnings;
use base qw (Blog::MoCo);
use Blog::MoCo::Entry;
__PACKAGE__->table('user');
__PACKAGE__->has_many(
entries => 'Blog::MoCo::Entry',
{ key => { id => 'user_id' } }
);
package Blog::MoCo::Entry;
use strict;
use warnings;
use base qw 'Blog::MoCo';
use Blog::MoCo::User;
__PACKAGE__->table('entry');
__PACKAGE__->has_a(
user => 'Blog::MoCo::User',
{ key => { user_id => 'id'} }
);
Setting up fixtures
Fixtures must be written in YAML and the file must have .yml extension.
Here's the structure of a fixture.
model: Your::MoCo::Class
records:
record_name1:
column1: foo
column2: bar
record_name2:
column1: baz
column2: quux
- model (mandate, unchangeable)
-
A name of a model which is correspondent to a fixture.
- records (mandate, unchangeable)
-
This field contains actual data to be inserted into your database.
- record_name1, record_name2 ... (changeable along with your convinience)
-
Names of each records. You can use this names as keys of a hash reference to the data in the fixture.
- column1, column2 ... (this names must be correspondent to the actual column names)
-
Names of each actual columns. This field contains the data of the column.
Well, fixtures()
method loads fixtures from fixtures directory which is located in the same level of *.t scripts directory. You can make the method to retrieve fixtures from other directory by passing optional parameters as below:
my $f = fixtures(qw(user entry), { yaml_dir => "../fixtures" });
Now you can write fixtures for testing like below:
user.yml
model: Blog::MoCo::User
records:
first:
id: 1
name: jkondo
second:
id: 2
name: naoya
entry.yml
model: Blog::MoCo::Entry
records:
first:
id: 1
user_id: 1
title: Hello World!
body: I'm fine!
second:
id: 2
user_id: 1
title: Cinnamon
body: The cutest dog ever!!!
Test Script
Finally, we'll start working on a test script using the fixtures above.
use strict;
use warnings;
use Test::More;
use FindBin::libs;
use Blog::MoCo::User;
use Blog::MoCo::Entry;
use DBIx::MoCo::Fixture;
# fixture() is exported from DBIx::MoCo::Fixture
my $fixtures = fixtures(qw(user entry));
plan tests => 8;
# Verifying if the data from db and from fixture are equal
is(Blog::MoCo::User->retrieve(1)->name, $fixtures->{user}{first}{name});
is(Blog::MoCo::User->retrieve(2)->name, $fixtures->{user}{second}{name});
is(Blog::MoCo::Entry->retrieve(1)->title, $fixtures->{entry}{first}{title});
is(Blog::MoCo::Entry->retrieve(2)->title, $fixtures->{entry}{second}{title});
is(Blog::MoCo::Entry->retrieve(1)->body, $fixtures->{entry}{first}{body});
is(Blog::MoCo::Entry->retrieve(2)->body, $fixtures->{entry}{second}{body});
# Verifying if has_a and has_many relationships work well
is(
Blog::MoCo::User->retrieve(1)->entries->find(sub { $_->id == 1})->title,
$fixtures->{entry}{first}{title}
);
is(
Blog::MoCo::Entry->retrieve(1)->user->name,
$fixtures->{user}{first}{name}
);
After you pass the names of fixtures into fixture()
method and execute it, this method automatically loads the fixtures and inserts the data into your database. The return value of the method is a hash reference whose keys are same as the names of the record names in fixtures you see above.
In this way, you can easily test your model classes by verifying if the data from database is equal to one from the fixture.
AUTHOR
Naoya Ito <naoya@bloghackers.net>
SEE ALSO
ACKNOWLEDGEMENT
It borrowed many codes from Test::Fixture::DBIC::Schema.
LICENSE
This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.