[Catalyst] testing catalyst app - need context

J. Shirley jshirley at gmail.com
Mon Mar 2 14:30:50 GMT 2009


On Mon, Mar 2, 2009 at 5:00 AM, David Wright <dave-catalyst at dexy.org> wrote:

> Ian Docherty wrote:
>
>> Kate Yoak wrote:
>>
>>> Hi there,
>>>
>>>
>>> Here is a newbie question:
>>>
>>> I like to test my functionality in bits and pieces as I write it.  How
>>> do I go about getting myself the context object in a test script?
>>>
>>> For example, one of the tests catalyst installs is t/model_App.t where
>>> it loads the model.  I'd love to then be able to use the model the same
>>> way a controller would:
>>>
>>> my $acc =3D $c->model('Account')->find(1);
>>>
>>> Instead, I am doing
>>> my $model =3D MyApp::Model::App->new();
>>> my $acc =3D $model->recordset('Account')->find(1);
>>>
>>> In addition to being less than ideal because I am doing something
>>> different that I expect real application code to do, it presents
>>> configuration problems.  Like, turns out, in order for config to take
>>> effect, I have to run __PACKAGE__->setup; after configuring it - which
>>> won't be necessary, I think, in a real app.
>>>
>>> Is the practice of unit tests that break up the layers of catalyst
>>> frowned upon? Or what should I do to make it work right?
>>>
>>>
>> Best practice is to keep your model separate from Catalyst so that you c=
an
>> (for example) create batch scripts or cron
>> jobs that work on the model without having to load the whole of Catalyst
>>
>> Your model then would be in something like MyApp::Storage and accessed by
>> your tests as so...
>>
>> my $schema =3D MyApp::Storage->connect(
>>   'DBI:mysql:host=3Dlocalhost;database=3Dmy_database',
>>   'username',
>>   'password',
>>   { 'mysql_enable_utf8' =3D> 1 },
>>   {on_connect_do =3D>[ 'set names utf8' ] }
>> );
>> my $acc =3D $schema->resultset('Account')->find(1);
>>
>> You would be testing your database layer separately from Catalyst.
>>
> Models aren't necessarily database layers.
>
> I'd suggest that with a sufficiently rich Catalyst application, the 'mode=
l'
> as known by Catalyst could easily become an effective 'controller' of a
> further model. That secondary controller is going to want to load model
> classes, and Catalyst provides a nice way of controlling instantiation.
>
> e.g.
>
> sub handle_payment : Path {
>  my ($self, $c, @args) =3D @_;
>
>  my $proc =3D $c->model('PaymentProcessor');
>  my $result =3D $proc->pay( { currency =3D> $args[0], amount =3D> $args[1=
], id =3D>
> $args[2] } );
>
>  $c->stash->{result}->{message} =3D $result->message;
>  $c->stash->{result}->{code} =3D $result->code;
> }
>
> # then, within PaymentProcessor
> sub pay {
>   my ($self, $args) =3D @_;
>
>   MyApp->model( 'Ledger' )->insert( { # blah } );
>   MyApp->model('Order')->update( { # blah } ) ;
> }
>
> This definitely does tightly couple the PaymentProcessor to the
> application. However, it also allows for better whitebox testing. If your
> logic is embedded within a Catalyst controller, the only sensible way to
> test it is to make an HTTP request. If it's in the model, the individual
> steps can be tested.
>
> FWIW, the principle here is "Catalyst controllers should do nothing except
> validate and translate HTTP parameters to 'model' parameters. They should=
n't
> manipulate model objects, or build complicated logic by combinations of
> model calls".
>
> Regards,
> David
>
>
>
>
It's good advice to have things standalone and available outside of
Catalyst, but your assessment of model dependencies stops short.

What you want is an independent model that accepts a schema object for
recording, and then a very thin adapter class inside of Catalyst.

What I would do is create something like MyApp::Payment and
MyApp::Storage::(Ledger|Order) -- then, in Catalyst have a
MyApp::Model::Payment adapter class that sets the $schema object on the
instantiated MyApp::Payment object as necessary.

This way, you can still dedecouple everything from a Catalyst app.  You
could have the payment stuff actually encapsulate MyApp::Storage, but I
don't see what that would give you.

-J
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.scsys.co.uk/pipermail/catalyst/attachments/20090302/686b9=
3f0/attachment.htm


More information about the Catalyst mailing list