3rdRailによるRailsプログラミング入門

第6回 Controllerクラスの実装と機能テスト(前編)

富田 陽介
Banana Systems株式会社

2009/8/17

機能テストコードの実装

 機能テストでは、Controllerのアクションメソッドごとに、メソッド処理の確認コードを実装していきます。

 都合の良いことに、スカフォルド機能でControllerを作成したことで、機能テストコードについてもベース部分が作成されています。

 そこで、まずはスカフォルド機能により作成された機能テストコードを確認していきます。

 [Railsエクスプローラー]からtsubuyakiプロジェクト−[テスト]−[機能テスト]の順にツリーを展開し、HitokotosControllerをダブルクリックすると、編集エリアに以下のとおりHitokotosControllerの機能テストコード(hitokotos_controller_test.rb)が表示されます。

●hitokotos_controller_test.rb
require 'test_helper'

class HitokotosControllerTest < ActionController::TestCase
  test "should get index" do
    get :index
    assert_response :success
    assert_not_nil assigns(:hitokotos)
  end

  test "should get new" do
    get :new
    assert_response :success
  end

  test "should create hitokoto" do
    assert_difference('Hitokoto.count') do
      post :create, :hitokoto => { }
    end

    assert_redirected_to hitokoto_path(assigns(:hitokoto))
  end

  test "should show hitokoto" do
    get :show, :id => hitokotos(:one).id
    assert_response :success
  end

  test "should get edit" do
    get :edit, :id => hitokotos(:one).id
    assert_response :success
  end

  test "should update hitokoto" do
    put :update, :id => hitokotos(:one).id, :hitokoto => { }
    assert_redirected_to hitokoto_path(assigns(:hitokoto))
  end

  test "should destroy hitokoto" do
    assert_difference('Hitokoto.count', -1) do
      delete :destroy, :id => hitokotos(:one).id
    end

    assert_redirected_to hitokotos_path
  end
end

 では、機能テストコードの書き方を含め、作成されたコードを確認していきましょう。

 上記のとおり、機能テストコードはActionController::TestCaseを継承したクラスへ記述します(ちなみに、Modelクラスのユニットテストコードは、ActiveSupport::TestCaseを継承したクラスに記述してきました)。このクラスを継承しておくことで、機能テストコード内において、Controllerへの各種HTTPリクエスト発行やレスポンス確認を行うための処理を簡単に記述できます。

 サンプルとして、上記のコードの最初のテストケースを見ていきましょう。

  test "should get index" do
    get :index
    assert_response :success
    assert_not_nil assigns(:hitokotos)
  end

 テストケースは、ユニットテストコードを記述したときと同様、testメソッドのブロック内に記述していきます。testメソッドへの引数も同様に、任意の文字列が指定できますので、テスト内容を表現した文字列を書いていくと良いでしょう。

 このテストケースでは、should get indexとなっていますので、このブロックでは「HitokotosControllerからindex(一覧)を取得できるべき」というテストを記述していることが分かります。

 続いて、ブロック内の処理も確認してみましょう。

 最初のget :indexという行を見てください。getはアクションメソッド名シンボルを引数にとるメソッドです。つまり、HitokotosControllerのindexアクションを呼び出すためのHTTP GETリクエストを発行することを示しています。

 同様にPOST、PUT、DELETEなどのHTTPリクエストに対応したメソッドも用意されています。後ほど出てきますので、確認しておきましょう。

 次に、assert_response :successという行ですが、ここではassert_responseというメソッドで、ControllerからのHTTPレスポンスを検証しています。引数として:successシンボルを指定することで、HTTPレスポンスのステータスコードが正常(200)であることが検証できます。

 ほかのステータスを検証するためのシンボルとして、:redirect(リダイレクト/ステータスコード3xx)、:missing(発見できず/ステータスコード404)、:error(エラー/ステータスコード5xx)なども指定できます。

 最後に、assert_not_nil assigns(:hitokotos)の行ですが、この行では、assigns(:hitokotos)の評価結果がnilでないことを検証しています。assignsというのは、引数としてControllerのインスタンス変数名をシンボル指定することで、そのインスタンス変数の持つ値を返すメソッドです。

 従って、この行では、HitokotosController#indexが実行されたとき、インスタンス変数@hitokotosがnilでないことを検証しています。

 つまり、このテストケースをまとめると「HitokotosControllerからindex(一覧)を取得できるべき」という検証ステップとして、

  1. HitokotosController#indexアクションを呼び出すHTTP GETリクエストを発行し、
  2. HTTPレスポンスのステータスコードが200であることを検証し、
  3. アクション実行後にインスタンス変数@hitokotosがnilでないことを検証する

という処理が書かれていることが分かります。

 続くnewアクションのテストケースは、indexと同様なので説明を飛ばします。続いて、createアクションのテストケースは、以下のようになっています。

  test "should create hitokoto" do
    assert_difference('Hitokoto.count') do
      post :create, :hitokoto => { }
    end

    assert_redirected_to hitokoto_path(assigns(:hitokoto))
  end

 ここでは、「HitokotosControllerがHitokotoモデルを作成できるべき」というテストが記述されています。

 assert_differenceという行ですが、これは、ある特定の処理の前後で、引数の値(評価結果)が変動することを検証するための行となっています。ある特定の処理は、assert_diferrenceのブロック内に記述します。

 ここでは、引数として'Hitokoto.count'を指定していますので、ModelクラスHitokotoのレコード数が、ブロック内の処理post :create, :hitokoto => { }の実行前後で変更されることを検証しています。

 このテストケースが実行される際の流れは以下のようになっていることになります。

  1. まず引数の評価を行い、その値を記録する
  2. ブロック内処理を実行する
  3. 再度、引数の評価を行い、1との差分をとる

 assert_differenceメソッドでのテストケース記述は、少しトリッキーな印象を受けるかもしれません。しかし、このように、ブロック処理の実行前後で所期の変化が起こったかどうかを検証するためのコードは、Controllerクラスが所期の働きをなしているかどうかの確認としてとても便利です。しっかりと確認しておきましょう。

 続くassert_redirected_to hitokoto_path(assigns(:hitokoto))という行では、アクションの実行後に、指定のパスへのリダイレクトが行われることを検証しています。ここでは、リダイレクト先のパスとしてhitokoto_path(assigns(:hitokoto))が指定されています。

 hitokoto_pathは「引数に指定されたModelクラスHitokotoに属するオブジェクト」を閲覧するためのパスを返すメソッドです。従って、ここではインスタンス変数@hitokotoに割り当てられたリソースを閲覧するためのパスへのリダイレクトが発生することを検証しています。

 hitokotos_controller_test.rbでは、ほかにも各種アクションメソッドのテストケースが記述されていますが、ここまでに紹介したテストコードとほぼ同形態のテストとなっているので、これ以上の説明は割愛します。ここでは、先に検討したHitokotosControllerで実装する機能に基づき、機能テストコードを以下のように書き換えておくこととします。

●hitokotos_controller_test.rb
require 'test_helper'
class HitokotosControllerTest < ActionController::TestCase
  test "indexへのGETリクエストが成功し、hitokotos変数に「ひとこと」リストが割り当てられる" do
    get :index
    assert_response :success
    assert_not_nil assigns(:hitokotos)
  end 

  test "newへのGETリクエストが成功し、users変数にユーザーのリストが割り当てられる" do
    get :new
    assert_response :success
    assert_not_nil assigns(:users)
  end 

  test "createへのPOSTリクエストにより、Hitokotoのレコード数が1増加し、一覧画面に遷移する" do
    assert_difference('Hitokoto.count', 1) do
      post :create, :hitokoto => { :user_id => 1, :hitokoto => 'コーヒー' } 
    end 
    assert_redirected_to hitokotos_path
  end 

  test "destroyへのDELETEリクエストにより、Hitokotoのレコード数が1減少し、一覧画面に遷移する" do
    assert_difference('Hitokoto.count', -1) do
      delete :destroy, :id => hitokotos(:banana).id
    end 

    assert_redirected_to hitokotos_path
  end 
end

 今回は、上記のとおり、index、new、create、destroyそれぞれのアクションメソッドを呼び出す際の機能テストを実装しました。テスト中で、前回までのModelクラスのユニットテストで作成したフィクスチャの読み込みも行っています。

prev
2/3
next

Index
Controllerクラスの実装と機能テスト(前編)
  Page1
Railsでよく使用されるアクションメソッド名
HitokotosControllerの実装
HitokotosControllerのアクションメソッド名
Page2
機能テストコードの実装
  Page3
機能テストコードを実行してみる

index 3rdRailによるRailsプログラミング入門

 Ruby/Rails関連記事
プログラミングは人生だ
まつもと ゆきひろのコーディング天国
 ときにプログラミングはスポーツであり、ときにプログラミングは創造である。楽しいプログラミングは人生をより実りあるものにしてくれる
生産性を向上させるRuby向け統合開発環境カタログ
Ruby on Rails 2.0も強力サポート
 生産性が高いと評判のプログラミング言語「Ruby」。統合開発環境を整えることで、さらに効率的なプログラミングが可能になる
かんたんAjax開発をするためのRailsの基礎知識
Ruby on RailsのRJSでかんたんAjax開発(前編)
 実はAjaxアプリケーション開発はあなたが思うよりも簡単です。まずはRuby on Railsの基礎知識から学びましょう
Praggerとnetpbmで作る画像→AA変換ツール
Rubyを使って何か面白いものを作ってみよう!
 一般的な画像をアスキーアートに変換するツールを作ってみる。さらに出力にバリエーションを持たせてみよう
コードリーディングを始めよう
Railsコードリーディング〜scaffoldのその先へ〜(1)
 優れたプログラマはコードを書くのと同じくらい、読みこなす。優れたコードを読むことで自身のスキルも上達するのだ
  Coding Edgeフォーラムフィード  2.01.00.91


Coding Edge フォーラム 新着記事
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

>

Coding Edge 記事ランキング

本日 月間