open_sessionで特異メソッドを定義するときの注意
open_sessionで特異メソッドを定義したら、変数の持ち主に注意しましょうというお話。
次のように定義したとします。
def user open_session do |u| def u.access_to_home get '/home/index' end end end
まず、これはエラーなく実行できます。
get '/home/index' assert_response :success
ところが、これはエラーしてしまいます。
@user = user @user.access_to_home assert_response :success #=> NoMethodError: undefined method `success?' for nil:NilClass
assert_response内で呼びだそうとした@responseは、テストを実行するコントローラがもつ変数です。
一方、@user.access_to_homeのレスポンスを受ける変数は@userセッションがもっているもので、コントローラから見た@responseとは別物なのですね。(あるいは、コントローラ自体がひとつのセッションだと見做すこともできる)
@user.access_to_homeのレスポンスを見るには、userの定義内で呼び出してやる必要があります。
def user open_session do |u| def u.access_to_home get '/home/index' assert_response :success end end end
今度はエラーなく実行できました。
@user = user @user.access_to_home
@user.responseと明示してやる方法もあります。
def user open_session do |u| def u.access_to_home get '/home/index' end end end
@user = user @user.access_to_home @user.response.success? # こちらも実行可 @user.assert_response :success
もしくは、instance_evalとか。
def user open_session do |u| def u.access_to_home(&block) get '/home/index' instance_eval(&block) if block end end end
@user = user @user.access_to_home do assert_response :success end