ページ

2016年1月7日木曜日

Rackアプリケーションのテスト - sham_rack -

新年一発目からマニアックです^^;
このブログにも散々投稿してる道の駅巡りですが、好きが高じて
道の駅の情報(位置など)を取得できるAPIを作成しました。
GithubにMichiEkiとして公開してます。
現在は道の駅の検索くらいしかできませんが、今後色々機能を
追加していきたい所です。

   本題


こっからが本題ですが^^;、このMichiEkiはrackアプリケーションとなっており
rackupコマンドで起動します。起動したMichiEkiアプリに対して色々な
リクエストを投げるとJSON形式でデータが返ってきます。
今回はこのRackアプリケーションのテストを書いていこうと思います。
テストはRSpecを使ってテストします。
  • 環境準備
bundle initを行い、できたGemfileに以下gemを追加します
gem 'rake'
gem 'rspec'
gem 'sham_rack'
↑でsham_rackというgemをインストールしてますが、
このgemがスタブやモックの働きをしてくれます。
インストールと初期化
$ bundle install
$ rspec --init
ここまでで以下のようなツリー構成になっているかと思います
.
├── Gemfile
├── Gemfile.lock
└── spec
    └── spec_helper.rb
サンプルとしてspec/hello.rbを作成します
# coding: utf-8

class HelloApp
  def call(env)
    case env['REQUEST_METHOD']
    when 'GET'
      [   
        200,
        { 'Content-Type' => 'text/html' },
        ['<html><body><p>hello</p></body></html>']
      ]   
    end
  end
end
単純にリクエストが来たらhelloを返しているだけのものです。
次にconfig.ruを作成します
# coding: utf-8

require_relative 'hello'

run HelloApp.new
ここまで作成できたら、一度試しに実行確認。
$ bundle exec rackup -o 0.0.0.0
http://localhost:9292/にアクセスしてhelloが表示されればOK

   sham_rackを使ったテスト


Rackアプリケーションをテストする際に便利なsham_rackというのがあります
sham_rackとは?
HTTPリクエストをホストに投げる前にフックすることができ、
モックやテスト用のドメインとしても使うことができます。
実際にsham_rackを使ってテストしていきます。
spec_helper.rbに以下を追加します。
require 'sham_rack'
require_relative '../hello'

RSpec.configure do |config|
  ・・・
end

ShamRack.at('sham.rack.example.com').rackup do
  run HelloApp.new
end
これでsham.rack.example.comに対してリクエストを送ると
フックされHelloAppが呼び出されます。
hello.rbのテストhello_spec.rbを以下内容で作成します
require "spec_helper"
require 'open-uri'

RSpec.describe HelloApp do

  it 'test hello' do
    result = open("http://sham.rack.example.com").read
    p result
    expect(result).to eq '<html><body><p>hello</p></body></html>'
  end
end
http://sham.rack.example.comにリクエストを送ると
<html><body><p>hello</p></body></html>が返ってくることを期待します
実行してみます。
$ bundle exec rspec
Run options: include {:focus=>true}

All examples were filtered out; ignoring {:focus=>true}
"<html><body><p>hello</p></body></html>"
.

Finished in 0.02474 seconds (files took 0.17352 seconds to load)
1 example, 0 failures
ちゃんとリクエストがフックされHelloApp#callが呼ばれ、
<html><body><p>hello</p></body></html>が返ってきてます。

4 件のコメント:

  1. すごいっす!!!API作るなんて...
    私もはやくこーゆーのを作れるぐらいになりたいっす!!

    返信削除
    返信
    1. APIと言ってるんですが、全然大した事やってなくて、
      使ってくれる人がいればいいな〜くらいのレベルです^^;

      削除
  2. いやいや、じゅうぶん大した事でしょ!
    新年早々、マニアックな記事で良いっすね。。

    返信削除
    返信
    1. ありがとうございます。
      あえて新年からマニアックにいってみましたw

      削除