[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