Railsでテストを書いてみる(Rspec:Controller編)

コントローラもテストしてみる。

  • ページにアクセスしてサクセスが返ることと、期待するテンプレートを表示することを確認するシンプルなケース
    • 画面にアクセスするのは get :アクション名
    • 成功が返るのは response.should be_success
    • テンプレートの表示判定は response.should render_template("XXXX")
  describe '登録画面にアクセスしたら' do
    before do
      get :add_index
    end

    it 'サクセスであること' do
      response.should be_success
    end

    it '登録画面を表示すること' do
      response.should render_template("tunes/add")
    end

  end
  • フォームからデータを送信したケースのテスト
    • post でアクションに対してパラメータを送ったことにする
    • データが登録されたことを直接DBを見て判定している。
    • リダイレクトの判定と、リダイレクト先を判定している
  describe '登録画面で曲を登録したら' do
    before do
      post :add_tune,{ :name => "Believe", :album => "Eternal Chain", :tuning => "CGDGBD"}
    end

    it '曲データが登録されること' do
      tune = Tune.find(:all, :conditions=>[ "name=?", 'Believe'])
      tune.length.should == 1
      tune[0].name.should == "Believe"
      tune[0].album.should == "Eternal Chain"
      tune[0].progress.should == 0
    end

    it '曲一覧画面を表示すること' do
      response.should be_redirect
      response.should redirect_to(:action => 'list')
    end
  end

直接DBの値を見ているけれど、DB登録したかどうかの判定は一枚モデルに登録用のラッパーをかませてそれを mock で判定したほうが良いのだろうか。まだよくわからない。

  • DBからデータを読み出して表示するページのテスト
    • mock を使って DB読み出ししたかを判定している。
    • mock の後に get しないとダメっぽい。before でまとめて get できないか。
  describe '曲一覧画面を表示した場合' do
    before do
#      get :list
    end

    it 'サクセスであること' do
      get :list
      response.should be_success
    end

    it 'DBから全曲を読み出すこと' do
      Tune.should_receive(:find).with(:all)
      get :list
    end

  end

mock が非常に使いやすい。上の例だと list アクション内で Tune.find(:all)しているかどうかを判定している

  • テスト対象のコードはこんな感じになった。意外とスカスカ
class TunesController < ApplicationController
  def add_index
  end

  def add_tune
    new_tune = Tune.new
    new_tune.name   = params[:name]
    new_tune.album  = params[:album]
    new_tune.tuning = params[:tuning]
    new_tune.progress = 0
    new_tune.save

    redirect_to :action => "list"
  end

  def list
    @tunes = Tune.find(:all)
  end
end

add_tune のアクション内で直接DB登録しているけれど、Slim3だったらサービスクラスに当たる登録用のラッパーをかませた方がいいような気がする。

  • それと、rake で spec の結果をいい感じの表示にする方法がわからない。 いろいろ調べると rake spec:doc かと思うんだけど、エラーになってしまうんだよなぁ‥。
$ rake spec:doc
(in /Users/hoge/rails_work/practice)
rake aborted!
Don't know how to build task 'spec:doc'

(See full trace by running task with --trace)

$ rake
(in /Users/hoge/rails_work/practice)
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby -S bundle exec rspec ./spec/controllers/tunes_controller_spec.rb ./spec/helpers/tunes_helper_spec.rb ./spec/models/tune_spec.rb
.........

Finished in 0.16196 seconds
9 examples, 0 failures