2011-02-16 80 views
2

可能是一個簡單的答案,它是模擬或存根相關的,但我是新手,試圖更好地理解事物......我試圖理解測試資源爲什麼不是實際的deleted?但規格通過,如果他們是?這可能(或可能不)是RSpec唯一的!!?瞭解RSpec和Rails測試環境

我有使用RSpec的一個新項目,並生成一個支架一個簡單的資源

$ rails new destroyer -T 
... 
$ rails generate rspec:install 
... 
$ rails g scaffold resource name:string 

一切正常,符合市場預期,並規範通過。但是我有一些奇怪的東西發生,並且測試另一個項目會失敗,因此在深入我加了一些記錄我的破壞方法,看看發生了什麼:

#app/controllers/resources_controller.rb 
def destroy 
    @resource = Resource.find(params[:id]) 
    @resource.destroy 
    logger.info "Resource Destroyed: #{@resource.destroyed?}" # <-- added 
    logger.info "Persisted after destroy: #{@resource.persisted?}" # <-- added 

    respond_to do |format| 
    format.html { redirect_to(resources_url) } 
    format.xml { head :ok } 
    end 
end 

當我銷燬資源我注意到這一點(### #)在我的日誌差異:

development.log

Started POST "/resources/3" for 127.0.0.1 at 2011-02-16 12:28:25 -0800 
    Processing by ResourcesController#destroy as HTML 
    Parameters: {"authenticity_token"=>"87+THlPY2Ni7vQCONbeSqwfoeXI2fesc7DIj6EMSaw=", "id"=>"3"} 
    Resource Load (0.2ms) SELECT "resources".* FROM "resources" WHERE "resources"."id" = 3 LIMIT 1 
    AREL (0.5ms) DELETE FROM "resources" WHERE "resources"."id" = 3 
Resource Destroyed: true    # <<<< ###### TRUE ###### 
Persisted after destroy: false 
Redirected to http://localhost:4002/resources 
Completed 302 Found in 30ms 

test.log中運行我看到這個規格後:

Processing by ResourcesController#destroy as HTML 
    Parameters: {"id"=>"1"} 
Resource Destroyed: false    # <<<< ###### FALSE ###### 
Persisted after destroy: false 
Redirected to http://test.host/resources 
Completed 302 Found in 4ms 

爲什麼我們會看到資源的不同狀態(destroyed?),這取決於我們運行的環境?

回答

3

如果您使用的是生成控制器的規格,你會看到類似這樣的摧毀行動:

require 'spec_helper' 

describe PostsController do 

    def mock_post(stubs={}) 
    @mock_post ||= mock_model(Post, stubs).as_null_object 
    end 

    it "destroys the requested post" do 
    Post.stub(:find).with("37") { mock_post } 
    mock_post.should_receive(:destroy) 
    delete :destroy, :id => "37" 
    end 
end 

該規範沒有實例化一個真正的Post對象,相反,它是用mock_model創建模擬(或'測試雙')。爲了使測試模型更容易,使用mock_model創建的模擬會刪除一些ActiveRecord方法,包括destroyed?persisted?。因此,這些模擬將不會像真實模型實例那樣運行。

0

我不確定,但似乎合乎邏輯的是,因爲每個示例在事務內部單獨運行,所以在事務提交之後,資源不會被標記爲已銷燬。如果你在Cucumber場景中運行同樣的東西,你可能會觀察到你在development.log中看到的結果。