今年の目標 ダイエット 13新卒の大曲です
Catalystでリクエスト元のIPアドレス によって処理を分岐させるコードがあったのですが、
テストコードでのテストはしていませんでした。
存在しなかったので、テストコード書くことにしました。
やったこと
・ LWP::UserAgent local_address
・ Test::WWW::Mechanize::Catalystの環境変数の設定
・ Plack::Test test_psgi
・ Test::WWW::Mechanize::PSGI
LWP::UserAgent local_address
Test::WWW::Mechanize::Catalystの親クラスにLWP::UserAgentがいたので、local_addressが利用できるのではないかと感じ 以下のコードで試しました。
結果は失敗でした。まねしないでください。
出来ない理由は以下の通りです。
Test::WWW::Mechanize::Catalystの親クラスとして
Test::WWW::Mechanize
WWW::Mechanize
LWP::UserAgent
があります。
以下のコードはWWW::Mechanizeのgetメソッドです。
なるほど、SUPER::getしてますね。
LWP::UserAgentのgetでは、requestを呼んでいるため
LWP::UserAgent->get
LWP::UserAgent->request
と思ってました。
でも、実際は違いました。
LWP::UserAgent->get
WWW::Mechanize->request
でした。
ちゃんとコメントにも書いてありますね。
# but it in turn calls the request() method here in Mechanize
さらにWWW::Mechanize->requestで_make_requestを呼んでました。
以下のコードは、WWW::Mechanizeの_requestです。
整理すると Test:::WWW::Mechanize::Catalystでgetを使うと
WWW::Mechanize->get
LWP::UserAgent->get
WWW::Mechanize->request
Test::WWW::Mechanize::Catalyst->_make_request
こんな感じの流れになります。
そのため、LWP::UserAgent->requestが呼ばれていないためHTTPのリクエスト生成時にlocal_addressが使用されないだろうと思いました。
また、LWP::UserAgentのDocumentに local_addressはIO::Socket::INETにLocalAddrとして渡すと書いてありました。
Get/set the local interface to bind to for network connections. The interface can be specified as a hostname or an IP address. This value is passed as the LocalAddr argument to IO::Socket::INET.
これでは確かに無理ですね!!!
Test::WWW::Mechanize::Catalystの環境変数の設定
今度はTest::WWW::Mechanize::Catalystで環境変数であるREMOTE_ADDRを渡す方法を探りました。Test::WWW::Mechanize::Catalyst(Version 0.59 )は、_do_catalyst_requestでリクエストを処理しています。
上のコードを見てもらえる分かるのですが、CATALYST_SERVERの有無をチェックしています。
(有)_do_remote_requestでCATALYST_SERVERにリクエストを投げる
(無)Catalyst::Test::_local_requestにCatalystのオブジェクトのインスタンスを渡す
ということになっています。
Catalyst::Test::_local_requestでは_requestを呼び出していました。
%extra_envにREMOTE_ADDRを設定できれば、いけることが分かると思います。
しかし、Test::WWW::Mechanize::Catalystの_do_catalyst_requestの段階で引数として渡せないため
Test::WWW::Mechanize::Catalystで環境変数の設定はできないみたいです。
Catalyst::Test::_local_request($self->{catalyst_app}, $request)
Plack::Test test_psgi
次に行ったことが Plack::Testを使った方法です。こちらは以下のコードで成功しました。
test_psgiでappに渡す内容は Catalyst::Test::_requestをパクって・・参考にしています。
Test::WWW::Mechanize::PSGI
Test::WWW::Mechanize::CatalystがダメだったのでTest::WWW::Mechanize::PSGIにしてみました
今回はTest::WWW::Mechanize::PSGIを利用しています。
また、簡単に切り替えができるように以下のようなメソッドで使ってます。
テストコードを少しずつ書くようにして半年経ちますが、
テストコードを書かないと不安になるようになりました。
そしてテストコードを書くのは楽しいです。
一つ一つの分岐を網羅していくのは、ドラクエのダンジョンで隅々まで網羅していくのと
同じ感覚です。
(開発では、完全網羅は難しいですけど)