Rack::Test と RSpec を使い Metal のテストを書く

Ruby on Rails のMetalを使ったコードのテストですが、RailsのIntegrationTestでテストできます。→ここを参照
しかし、一度RSpecを知ってしまうと従来のUnitTestには戻れません ^^); そこで Rack用のテスティングフレームワーク Rack::Test を使えば RSpec で Metal のテストが書けそうだと思い試してみました。

http://www.brynary.com/assets/2008/4/16/me_blog.jpg

require(File.dirname(__FILE__) + "/../../config/environment") unless defined?(Rails)

class Hello
  def self.call(env)
    request = Rack::Request.new(env)
    if env["PATH_INFO"] =~ /^\/hello/
      [200, {"Content-Type" => "text/html"}, ["Hello, #{request.params['name']}!"]]
    else
      [404, {"Content-Type" => "text/html"}, ["Not Found"]]
    end
  end
end

上の簡単な Metalのコードの Spec ですが以下のように書いたら動きました \(^O^)/

require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
require 'rack/test'

include Rack::Test::Methods
def app
  Rails::Rack::Metal.new(Hello)
end

describe Hello do
  fixtures :todos

  it "nameパラメタで渡された名前でHelloが表示される" do
    get "/hello", {"name" => "Yamada"}
    last_response.ok?.should be_true
    last_response.body.to_s.should == "Hello, Yamada!"
  end
end

このSpec(テスト)では fixture は使いませんが、普通に動作します。 Rack::Test と違うところは def app の中で Rails の Metalの initialize を呼び出してる部分のみです。


これで、安心して Metal も使えます ^^)