2011-01-10 28 views
0

我有一個Rails控制器,我無意中在'create'方法中定義了'edit'方法。儘管存在控制器錯誤,但我的測試仍然通過,但訪問編輯網址正確顯示錯誤。這是爲什麼?

我的控制器與所述錯誤:

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模板正確呈現;所有的實例變量都是可見的。所以所有的測試都通過了。

正確訪問'編輯'網址顯示錯誤;該模板使用@user實例變量,但它沒有正確設置。當然,更正控制器可以修復錯誤。

我不明白爲什麼測試通過了,爲什麼在測試中所有的實例變量值都可見?

我的本能表明這是一個範圍問題? @user是一個實例變量,在測試中它被設置在測試範圍內,但在我的控制器中,它在內部'編輯'方法的範圍內?但是測試如何找到'編輯'方法?內部的「編輯」方法存在於什麼範圍內?

+0

你能粘貼錯誤嗎? – Pasta 2011-01-10 10:02:16

回答

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操作(這會導致0123'方法被定義),以下請求也會再次卸載它。

但是,在測試環境中,如果較早的測試稱爲create操作,那麼該操作會爲將來的測試定義edit操作。如果你的測試是以不同的順序運行的話,你會看到一個不同的結果(這本身就是一個不好的主意,依靠這個)。

一般當然這不是你想要的,所以只需清理它並沿着:)

+0

現在我明白了。你剛剛教了我一些關於Ruby的新東西。我期待JavaScript的功能有範圍。 – 2011-01-10 10:32:29

相關問題