[Catalyst] getting $c in model unit test

Jonathan T. Rockway jon at jrock.us
Tue May 15 17:46:56 GMT 2007


On Tue, May 15, 2007 at 09:48:05AM -0400, Nathan Gray wrote:
> Does anyone have an example unit test that has access to $c?

As others have mentioned, this is probably a sign of a poorly designed
API.  If you decide to continue further, you'll probably want to use
Test::MockObject to setup a fake Catalyst app/context.  I have a class
called Angerwhale::Test::Application (code is on CPAN) that will setup a fake
Angerwhale context:

   sub context {
       my $args = shift;
       my $config = $args->{config};
   
       my $c = Test::MockObject->new;
       $c->set_always( 'stash', {} );
   
       $config = { %{$config||{}},
                   %{LoadFile('root/resources.yml')||{}}
                 };
   
       $c->set_always( 'config', $config );
   
       # fake logging (doesn't do anything)
       my $log = Test::MockObject->new;
       $log->set_always( 'debug', undef );
       $c->set_always( 'log', $log);
   
       # fake cache (always generates a cache miss)
       my $cache = Test::MockObject->new;
       $cache->set_always( 'get', undef );
       $cache->set_always( 'set', undef );
       $c->set_always( 'cache', $cache );
   
       # TODO: model / etc.

       return $c;
   }

As you can see, I only set up the stuff I use; in this case the stash,
a log, and $c->cache.  If I use something else, the test will die and I
can investigate why.

I also have a model function that returns an instance
of a model (and could be generalized to return any Component):

   sub model {
       my $name = shift;
       croak "need name" unless $name;
       my $args = shift;
       my $context = $args->{context} || context();
   
       $name =~ s/\W//g;
       $name = "Angerwhale::Model::$name";
   
       eval "require $name";
       croak "error loading $name: $@" if $@;
   
       my $model;
       eval {
           $model = $name->COMPONENT($context, $args->{args});
       };
       croak "didn't get a model: $@" if $@ || !$model;
   
       return $model;
   }

There's more than one way to do this, but it works for me.

Regards,
Jonathan Rockway



More information about the Catalyst mailing list