为什么Test :: WWW :: Mechanize :: PSGI使用端口?

时间:2013-12-28 09:33:09

标签: perl catalyst plack psgi

我有一些看起来像这样的代码:

use SomeApp;
use Test::WWW::Mechanize::PSGI;                                                                                                                                         
my $mech = Test::WWW::Mechanize::PSGI->new(
    app  => sub { SomeApp->run(@_) },
);
$mech->get_ok('/');

但是,只要调用get_ok(),我就会收到以下警告:

PSGI error: failed to listen to port 8080: Address already in use at .../5.18.1/HTTP/Server/PSGI.pm line 94.
HTTP::Server::PSGI::setup_listener('HTTP::Server::PSGI=HASH(0x7fe6622fad60)') called at .../5.18.1/HTTP/Server/PSGI.pm line 54

是的,我正在使用那个端口做其他事情。来自the docs of Test::WWW::Mechanize::PSGI

  

此模块允许您测试PSGI Web应用程序,但不需要服务器或发出HTTP请求。相反,它将HTTP请求对象直接传递给PSGI。

所以从理论上讲,我不需要指定一个端口,但是我得到了上面的警告,并且获取的页面返回500(它们在浏览器中工作正常)。我错过了什么?

  • 测试:: WWW :: Mechanize :: PSGI版本0.35
  • Plack版本1.0030
  • Catalyst版本5.90051

MyApp->run更改为MyApp->psgi_app会导致:

Can't call method "request" on an undefined value at .../5.18.1/Test/WWW/Mechanize/PSGI.pm line 47.

此错误可以通过以下方式复制:

catalyst.pl MyApp
cd MyApp
# run the test program above

2 个答案:

答案 0 :(得分:15)

Catalyst的run方法实际上会为开发运行HTTP服务器(通过Plack / PSGI!),这不是您通过PSGI进行测试所需的(不运行服务器)。你需要:app => MyApp->psgi_app,没有额外的sub块,因为psgi_app应该返回PSGI应用程序本身。

当您的应用返回根据PSGI规范不正确的内容时,错误消息“无法调用方法'请求'on ...”是一个常见错误。 git master上的消息有所改进,但它本质上是一个用户错误,因为当你只需要sub { $app }时,你基本上会返回$app

perldoc Catalyst::PSGI提供了有关使用Catalyst的PSGI支持的更多文档。

答案 1 :(得分:4)

Matt Trout提到LWP::Protocol::PSGI作为解决方法。它劫持HTTP以使其工作:

use Test::WWW::Mechanize;
use LWP::Protocol::PSGI;
use MyApp;

LWP::Protocol::PSGI->register( MyApp->psgi_app(@_) );
my $mech = Test::WWW::Mechanize->new;

# first GET must be absolute
$mech->get('http://localhost/login');
say $mech->content;

# then we can switch to relative
$mech->get('/login');
say $mech->content;

简而言之,上述内容或多或少受到了抨击(因为我不明白为什么第一个版本失败了),但这对我来说已经足够了。