0

「create」メソッド内に「edit」メソッドを誤って定義したRailsコントローラーがあります。

エラーのある私のコントローラー:

class UsersController < ApplicationController
...
  def create
    @user = User.new(params[:user])
    ...

    def edit
      @user = User.find(params[:id])
      @title = "Edit user"
      @check = "BORK" # something I added for testing the rendered output
    end
  end
end

テストの例。

it "should have the right title" do
  get :edit, :id => @user
  response.should have_selector('title', :content => 'Edit user')
end

したがって、テストを実行して(rspecを使用)、response.bodyを出力すると、ユーザーedit.html.erbテンプレートが正しくレンダリングされます。すべてのインスタンス変数が表示されます。したがって、すべてのテストに合格します。

'edit' URLにアクセスすると、エラーが正しく表示されます。テンプレートは@userインスタンス変数を使用しており、正しく設定されていません。もちろん、コントローラーを修正するとエラーが修正されます。

テストに合格する理由と、テストですべてのインスタンス変数値が表示される理由がわかりません。

私の本能は、これがスコープの問題であることを示唆していますか?@userがインスタンス変数であり、テストではテストのスコープ内に設定されていますが、私のコントローラーでは、内部の「edit」メソッドのスコープ内にありますか?しかし、テストはどのようにして「編集」メソッドを見つけるのでしょうか。その内部の「編集」メソッドはどのスコープに存在しますか?

4

1 に答える 1

3

コンストラクトはステートメントdefと同じくらい実行可能なコードであることを理解する必要があります。別のメソッド内に配置することは無効ではありませんが、外部メソッドが呼び出されるまで実行されませif

>> class Foo
>>   def foo
>>     def bar
>>     end
>>   end
>> end
=> nil 
>> Foo.instance_methods(false)
=> ["foo"] 
>> Foo.new.foo
=> nil 
>> Foo.instance_methods(false)
=> ["foo", "bar"] 

これがブラウザでエラーになった理由は、Railsがリクエストごとにすべての(ほとんどの)クラスをリロードするためです。したがって、アクションにアクセスした場合でも(メソッドが定義されるcreate原因になります)、次のリクエストによって再度アンロードされます。edit

ただし、テスト環境では、以前のテストでアクションが呼び出された場合、それによって将来のテストcreateのアクションが定義されます。editテストを異なる順序で実行すると、異なる結果が表示されます(これ自体、これに依存することはお勧めできません)。

一般的にもちろん、これはあなたが望むものではないので、それを片付けて進んでください:)

于 2011-01-10T10:19:06.813 に答える