2011-06-08 73 views
3

我目前正在從rails 2遷移到rails 3的過程中。在我們的功能規格,我們有很多的東西是這樣的:Rspec 2和Rails 3 stubbing/mocking

@model = Factory :model 
@child = Factory :child 
Model.stub!(:find).and_return(@model) 
Child.stub!(:find).and_return(@child) 

... 

@child.should_receive(:method).twice 

的主要問題是,如果我讓他打DB,並得到孩子的實際情況,真正:方法使得測試太複雜(需要兩個大工廠)和緩慢。

在代碼中,我們用各種方式來獲得項目:發現,動態查找等

@model = Model.find(1)  
@child = @model.children.find_by_name(name) 

你會如何建議,推動這一邏輯軌道3?對另一個存根/嘲笑圖書館的任何建議可能?

回答

10

通常你會嘲笑模型控制器的規格內:

Model.stub!(:find).and_return(mock_model('Model')) 
Child.stub!(:find).and_return(mock_model('Child')) 

但是,當你在你的軌道得到gem "rspec-rails", "~> 2.0" 3應用程序的Gemfile中,然後將標準導軌支架發生器將使用rspec的生成規範對你來說,運行rails generate scaffold MyResource會爲你生成一些示例規範。

以下是Rails/rspec將爲控制器規格生成的標註版本,所以我想這應該被認爲是「RSpec方式」。

describe AccountsController do 

    # Helper method that returns a mocked version of the account model. 
    def mock_account(stubs={}) 
    (@mock_account ||= mock_model(Account).as_null_object).tap do |account| 
     account.stub(stubs) unless stubs.empty? 
    end 
    end 

    describe "GET index" do 
    it "assigns all accounts as @accounts" do 
     # Pass a block to stub to specify the return value 
     Account.stub(:all) { [mock_account] } 
     get :index 
     # Assertions are also made against the mock 
     assigns(:accounts).should eq([mock_account]) 
    end 
    end 

    describe "GET show" do 
    it "assigns the requested account as @account" do 
     Account.stub(:find).with("37") { mock_account } 
     get :show, :id => "37" 
     assigns(:account).should be(mock_account) 
    end 
    end 

    describe "GET new" do 
    it "assigns a new account as @account" do 
     Account.stub(:new) { mock_account } 
     get :new 
     assigns(:account).should be(mock_account) 
    end 
    end 
end 
+0

我很高興我能夠給你的第一次給予好評:)我居然發現這一邊詢問有關RSpec的([這一個](類似的問題http://stackoverflow.com/questions/6557900/how-to-deal-with-mocking-nested-resources-in-rspec-and-rails) - 和David Chelimsky回答了它!)。無論如何,很高興在這裏見到你:) – Skilldrick 2011-07-02 23:53:35