LoginSignup
7
7

More than 5 years have passed since last update.

HTTP::Message::PSGIでPSGIアプリのテストを書く

Posted at

こんばんわ、こう見えてもPerl大好きなhirataraです。

PSGIのテストと言えばPlack::Testがデファクトスタンダードで、他にTest::WWW::Mechanize::PSGILWP::Protocol::PSGIを使う人もいると思います。
が、最近自分はテストを書くときにPlack付属のHTTP::Message::PSGIを直接使ってます。こいつはPSGIの入出力とHTTP::(Request|Response)を変換する極薄のラッパーです。

大体以下のような決まり文句で使ってます。

use strict;
use warnings;
use HTTP::Message::PSGI ();
use HTTP::Request::Common qw(GET);
use HTTP::Response;
use Test::More;

my $app = sub { [200, [], ["Hi\n"]] };

my $psgi_env = (GET "/")->to_psgi;
my $psgi_res = $app->($psgi_env);
my $res = HTTP::Response->from_psgi($psgi_res);

ok $res->is_success;

done_testing;

req_to_psgires_from_psgiいう2つのメソッドをexportしてくれるのですが、こいつよりもHTTP::RequestHTTP::Responseに直接生やされたメソッドがお気に入りです。
メソッドを生やす部分のHTTP::Message::PSGIの該当部分はこんな感じで実装されてます。簡潔かつ豪快で好感度高いですね!

sub HTTP::Request::to_psgi {
    req_to_psgi(@_);
}

sub HTTP::Response::from_psgi {
    my $class = shift;
    res_from_psgi(@_);
}

後、さらにソースを読むと$envREMOTE_ADDRREMOTE_PORTがlocalhost決め打ちであることに気が付きます。この辺はHTTPサーバが知っている情報なので、HTTP::Requestには知る由もないということです。偽装したければ戻ってきた$envを弄るといいでしょう。

薄いって以外の利点は特に思いつかないですが、薄さにこだわる紳士淑女の皆様は覚えておくと役に立つ日が来るかもしれません。
素の$env書くのとほぼ変わらない感じはありますが、HTTP::Request::Common::POSTを使えばリクエストディを伴う$envでもさらっと書けます。

my $env = (POST "/", Content => '{"hoge" : 1}')->to_psgi;

本当はテストには生$envを書きたいくらいの気持ちだけど、JSONをPOSTしたいからHTTP::Message::PSGIを使ってるというのが真相だったりします。

7
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
7