2011年8月23日火曜日

Rails3を初歩から学ぶ #8 create(テスト編)

この一連のエントリは
Ruby on Rails 3 Tutorial: Learn Rails by Example (Addison-Wesley Professional Ruby Series)
で参考に学んだことを凝縮してお送りしています。


前回showアクションを実装しました。今回は後回しにしていたcreateアクションを実装しましょう。前々回説明したようにnewアクションで表示されるページでボタンをクリックするとcreateアクションに処理が渡ります。ここで渡されたパラメータを元にDBに新規ユーザーを登録します。登録に成功したら登録したユーザーのページ(/users/:id)に遷移します。
これをやりたかったので前回showアクション(/users/:idで呼ばれる)を先に実装しました。

というわけでテストから。

describe "POST 'create'" do
describe "登録させないケースの検証" do
before(:each) do
@attr = {:name => "", :password => "", :password_confirmation => "" }
end
it "ユーザーを登録しないこと" do
lambda do
post :create, :user => @attr
end.should_not change(User, :count)
end
it "新規登録ページに戻ること(タイトル検証)" do
post :create, :user => @attr
response.should have_selector("title", :content => "新規登録")
end

it "新規登録ページに戻ること(テンプレート検証)" do
post :create, :user => @attr
response.should render_template('new')
end
end #登録させないケースの検証
describe "登録に成功するケースの検証" do
before(:each) do
@attr = { :name => "Cli lin", :password => "foobar",
:password_confirmation => "foobar" }
end
it "DBに新規ユーザーを登録していること" do
lambda do
post :create, :user => @attr
end.should change(User, :count).by(1)
end
it "ユーザー情報ページに遷移していること" do
post :create, :user => @attr
response.should redirect_to(user_path(assigns(:user)))
end
it "登録に成功した旨をユーザーに表示していること" do
post :create, :user => @attr
flash[:success].should =~ /登録に成功しました/
end
end #登録に成功するケースの検証
end # POST 'create'
ちょっと長いです。登録に成功するケースと失敗するケースそれぞれで別階層にテストを記述しています(describe文)。
検証時に「lambda」を使用している箇所があります。これは要求を実行した結果、データベースがどうなったかを検証するために使用します。これまで要求に対するResponseを検証していましたが、データベースの結果については応答では判定できないためこのようにlambdaでくくってやって実行結果に対して検証するようにしています。
「change(User, :count)」はUserモデルのレコード数(:count)の変化有無を確認するメソッドです。1つ増加したことを検証する場合は「change(User, :count).by(1)」とします。削除確認のときは「-1」にしてやります。

登録失敗時は再度新規登録画面を表示するため「Erender_template('new')」としてnewテンプレート(= new.html.erb)に遷移することを確認しています。
また登録成功時には「redirect_to(user_path(assgins(:user)))」として新規に登録したユーザーのidから生成したURL、つまり「/users/1」などといったパスにリダイレクトすることを検証しています。
ここで出てくる「user_path」とは何でしょう。
もう一度「rake routes」としてルート定義を見てみましょう。


users GET /users(.:format) {:action=>"index", :controller=>"users"}
POST /users(.:format) {:action=>"create", :controller=>"users"}
new_user GET /users/new(.:format) {:action=>"new", :controller=>"users"}
edit_user GET /users/:id/edit(.:format) {:action=>"edit", :controller=>"users"}
user GET /users/:id(.:format) {:action=>"show", :controller=>"users"}
PUT /users/:id(.:format) {:action=>"update", :controller=>"users"}
DELETE /users/:id(.:format) {:action=>"destroy", :controller=>"users"}

注目するのは左端、各GETメソッドに対して「users」や「new_user」と定義されています。これらはコード中に「users_path」とすると「/users」に、「new_user_path」とすれば「/users/new」に変換されることを示しています。
ここで使用している「user_path」は「/users/:id」に該当しますが、「:id」が変数に当たるので「user_path」のパラメータとして渡してやります。つまり「user_path(1) 」とすると「/users/1」に変換されます。テストコードでは「assigns(:user)」としてコントローラのインスタンス変数@userのidを渡しているわけです。
整理するとここではユーザーを新規に登録し、「/users/登録ユーザーID」にリダイレクトすることを検証していることになります。

最後にflashについて。flashはアクションをまたいで一時的に情報を保持する機能です。
「登録成功しました」「パスワード間違ってます」なんて情報を遷移先のページに表示させるために使います。自分で一時変数を用意すると値を消し忘れて、特定の遷移ルートをたどった時のみ変なメッセージが出てくるんですけど!なんて問題になりかねませんが、Railsにおけるflashは自動で削除してくれるので心配ありません。
ここでは登録成功時に「flash[:success]」に成功した旨の情報を格納していることを検証しています。

コントローラの実装は次回。

0 件のコメント:

コメントを投稿