nysus has asked for the wisdom of the Perl Monks concerning the following question:

I want to do test-driven development for a Dancer2 plugin I'm building. I'm a bit stymied on how to do unit testing for the plugin's functions. Here's a simplified example:

package Dancer2::Plugin::Menu ; use 5.010; use strict; use warnings; use Dancer2::Plugin; sub BUILD { my $plugin = shift; $plugin->_do_stuff } sub _do_stuff { my $plugin = shift; print Dumper $plugin; # does not print anything, undefined ... return $array_ref; }

Now let's say I want to unit test the do_stuff method in the above plugin:

use Test::Most tests => 1, 'die'; BEGIN { $ENV{'DANCER_ENVIRONMENT'} = 'testing'; } package TestApp; use Dancer2; use Dancer2::Plugin::Menu; use Data::Dumper qw 'Dumper'; get '/' => sub { return 'hello' }; get '/test' => sub { return 'hi' }; # do_stuff method gets called, but no object is passed to it so functi +on won't work properly deep_cmp [ '/', '/test' ], Dancer2::Plugin::Menu::do_stuff, 'returns e +xpected array';

As pointed out in the comment above, this doesn’t work because the plugin object doesn’t get passed to the method. One possible workaround is to export the do_stuff method and all the other methods I want to unit test with plugin_keywords but this seems hacky. Is there a better approach?

$PM = "Perl Monk's";
$MCF = "Most Clueless Friar Abbot Bishop Pontiff Deacon Curate Priest Vicar";
$nysus = $PM . ' ' . $MCF;
Click here if you love Perl Monks

Replies are listed 'Best First'.
Re: How can you unit test a Dancer2 plugin mehod?
by 1nickt (Canon) on Nov 10, 2018 at 15:23 UTC

    Hi, it's not clear to me what you are trying to do, in your code or in your test. You declare a sub _do_stuff in your plugin class, but try to test a sub named do_stuff. You should create an SSCCE that we can download and run so we can help.

    The main point of the Dancer2 plugin framework is to add keywords to the DSL that can be used in route code -- maybe you are trying to accomplish something that is not best accomplished with a plugin?

    Anyhow, to answer what I think is your specific question, if you want your subroutine in the plugin class to get its class name as the first arg, without exporting the keyword and using the Moo inheritance as designed, you must call it as a class method:

    Dancer2::Plugin::Menu->do_stuff()

    Hope this helps!


    The way forward always starts with a minimal test.
Re: How can you unit test a Dancer2 plugin mehod?
by nysus (Parson) on Nov 10, 2018 at 12:57 UTC

    I found a decent solution, I think. Go down a layer of abstraction and create a Dancer2::Core::App object and modify it with provided methods.

    my $app = Dancer2::Core::App->new(); $app->with_plugins( 'Menu' ); $app->add_route( method => 'get', regexp => '/test', code => sub {return 'hi'}, ); Dancer2::Plugin::Menu::_do_stuff($app);

    $PM = "Perl Monk's";
    $MCF = "Most Clueless Friar Abbot Bishop Pontiff Deacon Curate Priest Vicar";
    $nysus = $PM . ' ' . $MCF;
    Click here if you love Perl Monks