Dancer Simple Session and testing a session
In this example you'll see how to use a session to store some information sent in by a user and how to retreive it in another request. You'll also see how to test it.
Directory Layout
. ├── bin │ └── app.pl ├── lib │ └── App.pm └── t ├── 01-index.t └── 02-psgi.t
Code launching the app
examples/dancer/app5/bin/app.pl
#!/usr/bin/env perl use Dancer; use App; dance;
The code of the application
examples/dancer/app5/lib/App.pm
package App; use strict; use warnings; use Dancer ':syntax'; set session => 'Simple'; get '/' => sub { my $text = session('txt') // ''; return qq{ <h1>Session</h1> Currently saved: <b>$text</b><p> <form action="/save" method="POST"> <input type="text" name="txt"> <input type="submit" value="Send"> </form> <p> <a href="/delete">delete text</a> }; }; post '/save' => sub { my $text = param('txt'); session txt => $text; return qq{ You sent: <b>$text</b><p> Check it on the <a href="/">home page</a> }; }; get '/delete' => sub { session txt => undef; return 'DONE <a href="/">home</a>'; }; true;
The test code
examples/dancer/app5/t/01-index.t
use Test::More tests => 7; use strict; use warnings; # the order is important use App; use Dancer::Test; my $text1 = 'Hello World!'; my $text2 = 'Some other text'; subtest index => sub { my $resp = dancer_response GET => '/'; is $resp->status, 200; like $resp->content, qr{<h1>Session</h1>}; like $resp->content, qr{<form}; like $resp->content, qr{<b></b>}; }; subtest save => sub { my $resp = dancer_response POST => '/save', { params => { txt => $text1, } }; is $resp->status, 200; like $resp->content, qr{You sent: <b>$text1</b>}; }; subtest index => sub { my $resp = dancer_response GET => '/'; is $resp->status, 200; like $resp->content, qr{<h1>Session</h1>}; like $resp->content, qr{<form}; like $resp->content, qr{<b>$text1</b>}; }; subtest save => sub { my $resp = dancer_response POST => '/save', { params => { txt => $text2, } }; is $resp->status, 200; like $resp->content, qr{You sent: <b>$text2</b>}; }; subtest index => sub { my $resp = dancer_response GET => '/'; is $resp->status, 200; like $resp->content, qr{<h1>Session</h1>}; like $resp->content, qr{<form}; like $resp->content, qr{<b>$text2</b>}; }; subtest delete => sub { my $resp = dancer_response GET => '/delete'; is $resp->status, 200; like $resp->content, qr{DONE}; }; subtest index => sub { my $resp = dancer_response GET => '/'; is $resp->status, 200; like $resp->content, qr{<h1>Session</h1>}; like $resp->content, qr{<form}; like $resp->content, qr{<b></b>}; };
Testing with Test::WWW::Mechanize::PSGI
Test::WWW::Mechanize::PSGI is an excellent testing library that makes it easy to create more complex interactions and to represent more than one browsers at the same time. So you can observe that while one user ($mech1) sees the newly set text use two $mech2 does not.
examples/dancer/app5/t/02-psgi.t
use Test::More tests => 4; use strict; use warnings; # the order is important # load all the parts of the Application (including hooks) # before loading the Test:: module. use App; use Test::WWW::Mechanize::PSGI; my $text1 = 'Hello World!'; my $text2 = 'Some other text'; my $mech1 = Test::WWW::Mechanize::PSGI->new( app => Dancer::Handler->psgi_app ); my $mech2 = Test::WWW::Mechanize::PSGI->new( app => Dancer::Handler->psgi_app ); subtest index => sub { $mech1->get_ok( '/' ); $mech1->content_like( qr{<h1>Session</h1>} ); $mech1->content_like( qr{<b></b>} ); }; subtest save => sub { $mech1->post_ok('/save', { txt => $text1, }); $mech1->content_like( qr{You sent: <b>$text1</b>} ); }; subtest index => sub { $mech1->get_ok( '/' ); $mech1->content_like( qr{<h1>Session</h1>} ); $mech1->content_like( qr{<b>$text1</b>} ); }; subtest index_another_browser => sub { $mech2->get_ok( '/' ); $mech2->content_like( qr{<h1>Session</h1>} ); $mech2->content_like( qr{<b></b>} ); };
Running the tests
Be in the root directory of your project. (The common parent directory of bin, lib, and t.) and type:
prove -l
Published on 2019-04-26