FAQ
I have a question about writing unit tests for a Catalyst app.

I've found it's extremely useful to have internal controller tests, as
described on http://www.catalystframework.org/calendar/2006/17 ("Chuck
Norris tests his Catalyst controllers with Test::More").

The basic approach I've been using is like this:

--------------------------------
use Test::More tests => 1;
use lib 'lib';
use MyApp;
require 'mock_interface';

my $c = MyApp->new;
$c->req->param->{foo} = 3;
$c->req->param->{bar} = 4;
MyApp::Controller::MyCntrl::my_method(undef, $c);
ok( $c->stash->{baz}, 25, "calculated baz and stash'd it" );
--------------------------------

Then, what I did in mock_interface was a lot of this kind of thing:

--------------------------------
my %stash = ();
*MyApp::stash = sub { \%stash };
--------------------------------

Basically, this is a mock-up of a minimal interface for the context object,
which I pass directly to controller methods. I had to re-implement stash,
session, req->param (and all its aliases), and res->body (and all its
aliases). I may need more later.

My question is...

Is there a way to get a fully instantiated and interfaceable $c outside of
the server without having to maintaining my own separate mock implementation
of it?

I've looked at Catalyst::Test, Test::WWW::Mechanize::Catalyst, Catalyst,
Catalyst::Engine, and Catalyst::Request, but none of them seem to contain a
full-fledged $c independently of the server startup process.

Search Discussions

  • Matt Lawrence at Apr 17, 2007 at 4:45 pm

    Andrew Strader wrote:
    I have a question about writing unit tests for a Catalyst app.

    I've found it's extremely useful to have internal controller tests, as
    described on http://www.catalystframework.org/calendar/2006/17 ("Chuck
    Norris tests his Catalyst controllers with Test::More").

    The basic approach I've been using is like this: [snip]
    My question is...

    Is there a way to get a fully instantiated and interfaceable $c outside of
    the server without having to maintaining my own separate mock implementation
    of it?

    I've looked at Catalyst::Test, Test::WWW::Mechanize::Catalyst, Catalyst,
    Catalyst::Engine, and Catalyst::Request, but none of them seem to contain a
    full-fledged $c independently of the server startup process.
    Just noticed this unanswered question in Phaylon's very helpful summary..

    When I wanted to do something similar, I did:


    my $controller = MyApp->controller('MyController');
    my $c = MyApp->prepare();

    # Monkey with $c to set up a fake context (set req->uri, or params)

    my $result = $controller->method_to_test($c, @args);


    Which worked for me in the very narrow context I was working in (I just
    wanted to check the return value of the method).

    I'm sure someone more familiar with the internals of Catalyst could tell
    you more about the pros and cons of this approach. One obvious drawback
    is the inability to forward to other actions from the one you're testing.

    Cheers,

    Matt
  • Matt Lawrence at Apr 17, 2007 at 5:37 pm

    Matt Lawrence wrote:
    Andrew Strader wrote:
    I have a question about writing unit tests for a Catalyst app.

    I've found it's extremely useful to have internal controller tests, as
    described on http://www.catalystframework.org/calendar/2006/17 ("Chuck
    Norris tests his Catalyst controllers with Test::More").

    The basic approach I've been using is like this:
    [snip]
    My question is...

    Is there a way to get a fully instantiated and interfaceable $c outside of
    the server without having to maintaining my own separate mock implementation
    of it?

    I've looked at Catalyst::Test, Test::WWW::Mechanize::Catalyst, Catalyst,
    Catalyst::Engine, and Catalyst::Request, but none of them seem to contain a
    full-fledged $c independently of the server startup process.
    Just noticed this unanswered question in Phaylon's very helpful summary..

    When I wanted to do something similar, I did:


    my $controller = MyApp->controller('MyController');
    my $c = MyApp->prepare();

    # Monkey with $c to set up a fake context (set req->uri, or params)

    my $result = $controller->method_to_test($c, @args);


    Which worked for me in the very narrow context I was working in (I just
    wanted to check the return value of the method).

    I'm sure someone more familiar with the internals of Catalyst could tell
    you more about the pros and cons of this approach. One obvious drawback
    is the inability to forward to other actions from the one you're testing.
    Scratch that. I've just realised that you can forward in the tested
    action if you call it with $c->forward in the test code, instead of
    calling the method directly.

    Matt
  • Ash Berlin at Apr 17, 2007 at 5:52 pm
    Andrew Strader wrote:
    [snip]

    I see no round house kicks....
  • Matt Lawrence at Apr 17, 2007 at 6:05 pm

    Ash Berlin wrote:
    Andrew Strader wrote:
    [snip]

    I see no round house kicks....
    .. until it's too late!

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupcatalyst @
categoriescatalyst, perl
postedMar 27, '07 at 4:01p
activeApr 17, '07 at 6:05p
posts5
users3
websitecatalystframework.org
irc#catalyst

People

Translate

site design / logo © 2021 Grokbase