読者です 読者をやめる 読者になる 読者になる

maeshimaの日記

メモ書きです

Chapter 25 Rails Controllers

Rails controller の spec の書き方について。

25.1 Controller Specs

  • ModelName.new も疎結合のためにstubを実装したほうがいい。
  • mock_modelってなんだっけ -> new_record?やidなどの基本的なstubがついてるmock

adding context specific examples

成功時、失敗時それぞれのspecをかく。

what we just did

require 'spec_helper'

は忘れずに。

controllerのspecで使われるメソッドは主にActionControlelr::TestCaseで定義されている。例えば

  • assigns[]
  • flash[]

とか。使い方は省略。

post

postの引数は

post :create, {:id => 2}, {:user_id => 99}

のように、action, params, sessionの順番。xhr も同じような感じで使える。

render_template

response.should render_template("messages/new")
# MessagesController spec内であれば下記でもおk
response.should render_template("new")
# 拡張子もテストできる
response.should render_template("new.js.erb")

25.2 Application Controller

application controllerのspecを書く方法について。

まず、ApplicationController を 継承したcontrollerの定義をspec中に書く。続いて

controller_name 'foo'

で get や post 時のcontrollerを設定する(設定しないとdescribeで指定したコントローラにリクエストが行くのだと思う)。さらにrouting定義もspec中に書く(オーバライドする)。

before(:each) do
  ActionController::Routing::Routes.draw do |map|
    map.resources :foo
  end 
end

# example終了後にちゃんとroutingを元に戻す
after(:each) do
  ActionController::Routing::Routes.reload!
end

これでおk。

25.3 FAQ

ファイルアップロードのテスト方法

ActionController::TestUploadedFile を使うと、ファイルアップロードのテストが書ける

describe UsersController, "POST create" do
  after do
    # if files are stored on the file system
    # be sure to clean them up
  end
  it "should be able to upload a user's avatar image" do
    image = fixture_path + "/test_avatar.png"
    file = ActionController::TestUploadedFile.new image, "image/png"
    post :create, :user => { :avatar => file }
    User.last.avatar.original_filename.should == "test_avatar.png"
  end 
end

emailの送信テスト

普通にModelのstub書く感じでよさげ

filterのテスト

filterのspecは普通書かないみたい?でも下記のように、filterでcontrollerの挙動が変わるときはチェックするみたい。

describe EventsController do
  context "accessed by an anonymous visitor" do
    it "denies access to the create action" do
      controller.should_not_receive(:create)
      post :create
    end
  end
end

ていうか controller で controller のインスタンスにアクセスできるの?しらんかった