Ruby Freaks Lounge

第24回 Rackとは何か(2)Rackの使い方

この記事を読むのに必要な時間:およそ 3 分

Rack::MockRequest

Webアプリケーションを書く際,きちんと動くかどうかテストコードを書いて検証することがあると思います。実際にリクエストを投げるスクリプトやSeleniumなどのツールを使ったり,Railsなどではフレームワーク付属のテスト用のライブラリを使ったりすることになると思いますが,Rackではテストを補助するためのライブラリも用意されています。

以下のコードはSimpleAppの挙動をテストする単体テストですが,実際にリクエストを投げるのではなく,MockRequestを使用してサーバにリクエストを投げたときの挙動をテストしています。

# coding: utf-8

require 'simple_app'
require 'test/unit'
require 'rack/mock'

class SimpleAppTest < Test::Unit::TestCase
  def setup
    @app = SimpleApp.new
    @mr  = Rack::MockRequest.new(@app)
  end

  def test_get
    res = nil
    assert_nothing_raised('なんか失敗した') { res = @mr.get('/', :lint => true) }
    assert_not_nil res, 'レスポンス来てない'
    assert_equal 200, res.status, 'ステータスコードが変'
    assert_equal 'text/html;charset=utf-8', res['Content-Type'], 'Content-Typeが変'
    assert_match /見たい?/, res.body, '本文が変'
  end

  def test_post
    res = nil
    assert_nothing_raised('なんか失敗した') { res = @mr.post('/', :lint => true) }
    assert_not_nil res, 'レスポンス来てない'
    assert_equal 200, res.status, 'ステータスコードが変'
    assert_equal 'text/html;charset=utf-8', res['Content-Type'], 'Content-Typeが変'
    assert_match /何見てんだよ。/, res.body, '本文が変'
  end
end

これを利用することで,Railsのコントローラのテストのようにサーバを立ち上げなくてもアプリケーションのテストができますし,実際にRamazeなどはRack::MockRequestを使用してフレームワークのテストライブラリを作っています。また,Rackのテストをより簡単にできるようにするRack::Testのようなライブラリもありますので,Rackアプリケーションを作る場合は利用するとよいでしょう。

Rack::URLMap

Rack::URLMapはRackの「機能」ではなくRack標準添付の「アプリケーション」なのですが,Rack::Builderにも上手く組み込まれていて便利なので紹介しておきます。

このアプリケーションはパスとアプリケーションのマッピングを保持しておき,パスに応じてリクエストを登録してあるアプリケーションに振り分けてくれます。また,Rack::Builderではこのアプリケーションへのショートカットになっているmapという記法が用意されています。

例えば,以下のように使います。

# config: utf-8

require 'simple_app'
require 'rack/lobster'

map '/simple' do
  run SimpleApp.new
end

map '/lobster' do
  # Rackをインストールすると
  # サンプルとして付いてくるアプリケーション
  # ちょっと面白い
  run Rack::Lobster.new
end

config.ruを書き換えたらrackupして,http://localhost:9292/http://localhost:9292/simplehttp://localhost:9292/lobsterそれぞれにアクセスしてみてください。mapで指定した通りに振り分けられ,対応しないパスの時は表示できないことが確認できるはずです。

ちなみに,Rack::URLMapをRack::Builderをからではなく使う場合は,以下のようにします。

urlmap = Rack::URLMap.new( '/simple' => SimpleApp.new, '/lobster' => Rack::Lobster.new )

Rack::URLMapでは複雑なURLの解決はできませんので,通常はアプリケーションやフレームワークの側で実装することになりますが,単機能の簡単なアプリケーションを複数立ち上げたいというような場合には手軽に設定できて便利です。

まとめ

今回は,Rack::Builder,リクエスト/レスポンスの扱い方,テストの仕方,URLのマッピングについてをご紹介しました。ここまでで一通り,Rackアプリケーションを作るにあたって知っておいた方がいいことに触れられたと思いますので,あとは実際にアプリケーションを作って試してみてください。

次回は,Rackの「インターフェースの統一」と並んで重要な仕組みである「ミドルウェア」についてご紹介したいと思います。

著者プロフィール

佐孝太郎(さこうたろう)

株式会社ライブドア所属。仕事では主にPerlとObjCを使っているものの, MacRubyでCocoaアプリのテストを書くなど,隙を見付けてはRubyを使おうと目論んでいる。

bloghttp://blog.livedoor.jp/faulist/
twitter:http://twitter.com/faultier