控制器測試


控制器通常必須與其它元件互動,例如模型,所以在Rails後,會假設控制器測試是功能測試,你產生一個控制器,就會有相對應的測試檔案放置在test/functional中。例如 觀摩 Scaffold 中產生了messages_controller.rb,就產生了對應的test/functional/messages_controller_test.rb,可觀摩其中如何對控制器進行測試:

  • messages_controller_test.rb
class MessagesControllerTest < ActionController::TestCase
  setup do
    @message = messages(:one)
  end

  test "should get index" do
# GET請求index動作
  get :index
# 斷言200成功回應 assert_response :success
# 斷言控制器設定了messages實例變數
 assert_not_nil assigns(:messages) end test "should get new" do get :new assert_response :success end test "should create message" do
# 在程式區塊執行完畢後,Message對應表格的資料筆數一定會多一筆
 assert_difference('Message.count') do
# POST請求create動作,params[:message]就是@message.attributes post :create, message: @message.attributes end

 # 斷言設定了message實例變數並重導至messages/:id assert_redirected_to message_path(assigns(:message)) end test "should show message" do
# GET請求show動作,id請求參數設為@message.to_param
 get :show, id: @message.to_param assert_response :success end test "should get edit" do get :edit, id: @message.to_param assert_response :success end test "should update message" do
# PUT請求update動作
 put :update, id: @message.to_param, message: @message.attributes assert_redirected_to message_path(assigns(:message)) end
test "should destroy message" do
# 在程式區塊執行完畢後,Message對應表格的資料筆數一定會少一筆
 assert_difference('Message.count', -1) do
# DELETE請求destroy動作 delete :destroy, id: @message.to_param end assert_redirected_to messages_path end end

Rails在控制器測試時,提供了幾個請求方法:

  • get
  • post
  • put
  • head
  • delete

實際上控制器測試時,並不會區別這幾個方法的差別,只是為了在測試時更具語意而已,這幾個方法會發出請求,呼叫時可依序接受四個參數:

  • Symbol或字串指定要請求的動作
  • 選擇性以Hash指定請求參數
  • 選擇性以Hash指定session資料
  • 選擇性以Hash指定flash資料

例如想請求show動作,請求參數id為1,而session中user_id設為5,可如下呼叫

get(:show, {'id' => "12"}, {'user_id' => 5})

例如想請求view動作,請求參數id為12,不設餐session,但設定flash中message為booya

get(:view, {'id' => '12'}, nil, {'message' => 'booya!'})

在請求被控制器的相關動作處理之後,可以使用以下幾個方法取得控制器中設定的資料:

  • assign:取得控制器中設定的實例變數
  • cookies:取得cookies傳回物件
  • session:取得session傳回物件
  • flash:取得flash傳回物件

除此之外,還可以使用以下幾個變數,取得控制器中的三個實例變數:

  • @controller
  • @request
  • @response
例如若要設定請求中的cookie,可以如下:

@request.cookies[:user] = "caterpillar"