Mojolicious框架states接下来:
可以从Test :: Mojo通过应用程序对象自省应用程序的任何方面(助手,插件,路由等)。
但是,例如当助手$c->current_user
处理会话时,它将失败。
会话数据不可用,我无法从测试中访问它:
$t->app->session # {}
因此$t->app->current_user
也失败了。
如何从测试访问会话数据?
UPD 测试
use Mojo::Base -strict;
use Mojolicious::Lite;
use Test::More;
use Test::Mojo;
get '/set_session' => sub {
my $c = shift;
$c->session->{ user_id } = 1;
$c->render( text => $c->session->{ user_id } );
};
get '/get_session' => sub {
my $c = shift;
$c->render( text => $c->session->{ user_id } );
};
my $t = Test::Mojo->new;
$t->get_ok( '/set_session' )->status_is(200);
is $t->app->session->{ user_id }, 1, 'Session available from test script';
$t->get_ok( '/get_session' )->status_is(200)
->content_is( 1 );
done_testing();
UPD 测试结果
ok 1 - GET /set_session
ok 2 - 200 OK
not ok 3 - Session available from test script
# Failed test 'Session available from test script'
# at t/session.t line 22.
# got: undef
# expected: '1'
ok 4 - GET /get_session
ok 5 - 200 OK
ok 6 - exact match for content
1..6
# Looks like you failed 1 test of 6.
UPD
似乎Mojo::Test
对象除the request and response objects from the previous transaction
之外还应保存会话对象
答案 0 :(得分:2)
要在上一个请求的上下文中测试帮助程序,我编写下一个角色:
package Test::Mojo::Role::Helper;
use Mojo::Base -role;
sub helper {
my( $t ) = @_;
$t->tx->req->cookies( @{ $t->tx->res->cookies } );
$t->app->build_controller( $t->tx );
}
1;
然后将其用作下一个:
use Test::Mojo;
my $t = Test::Mojo->with_roles( '+Helper' )->new( 'MyApp' );
$t->post_ok( '/login', json => { contact => $user_c, password => $user_p } )
->status_is( 200 );
is $t->helper->uid, 1, "Authorized user has identificator";
is $t->helper->role, 'user', "Authorized user has 'user' privilege";
UPD 更强大的解决方案
package Test::Mojo::Role::Helper;
use Mojo::Base -role;
my $req_context; # Here is controller object
sub helper { $req_context }
sub hook_context {
my( $t ) = @_;
$t->app->hook( after_dispatch => sub{ $req_context = shift });
$t;
}
1;
测试与下一个小差异相同。构建应用程序时,我们应该挂接到after_dispatch
事件:
my $t = Test::Mojo
->with_roles( '+Helper' )
->new( 'App' )
->hook_context;
答案 1 :(得分:1)
Test::Mojo
类无法直接访问会话内容。测试类代表您的Mojolicious应用程序的客户端,并且该客户端也不具有对会话cookie的直接访问权限(嗯,它只是base64编码的JSON,因此它不是完全秘密的,但仍然……)。
测试会话的“正确”方法是检查与会话有关的应用程序行为,而不仅仅是检查会话是否设置为某个值。实际上,这就是您的/get_session
端点所做的事情。当然,您不仅应该添加这样的端点进行测试,还应该考虑会话如何适合您的需求。例如。作为BDD风格的场景:
Feature: the secret page
there is a secret page that should be only visible to logged-in users.
Background:
Given a user "test:test123"
Given a new client
Scenario: users cannot see the page when they are not logged in
When I visit the /secret page
Then I get a 404 response
Scenario: users can see the page after logging in
Given I log in as "test:test123"
When I visit the /secret page
Then I see "this is the secret"
$t->app->session
不包含会话,因为会话数据已加载到控制器的stash
中。这仅在请求期间存在。特别是app->session
仅仅是委派给当前控制器的助手,而不是应用程序的主要方法。
如果您确实需要窥视会话cookie,这可能是最疯狂的方法,而无需夸大控制器对象:
my ($session) = grep { $_->name eq $t->app->sessions->cookie_name } $t->ua->cookie_jar->all->@*;
$session = $session->value =~ s/--[^-]+$//r; # strip signature
$session =~ tr/-/=/;
$session = $t->app->sessions->deserialize->(Mojo::Util::b64_decode $session);