2012-10-06 70 views
0

我寫這個來測試我的控制器的使用嵌套資源的創建動作。我有一個與has_many :users關聯的帳戶模型。註冊後,將創建一個擁有單個用戶的帳戶。使用RSpec測試嵌套資源會導致奇怪的失敗

describe "POST #create", focus: true do 
    let(:account) { mock_model(Account).as_null_object } 

    before do 
     Account.stub(:new).and_return(account) 
    end 

    it "creates a new account object" do 
     account_attributes   = FactoryGirl.attributes_for(:account) 
     user_attributes   = FactoryGirl.attributes_for(:user) 
     account_attributes[:users] = user_attributes 

     Account.should_receive(:new).with(account_attributes).and_return(account) 
     post :create, account: account_attributes 
    end 
    end 

這是我得到的失敗輸出;注意預期和得到的區別:它在得到一個字符串的時候預期了一個符號。

1) AccountsController POST #create creates a new account object 
    Failure/Error: Account.should_receive(:new).with(account_attributes).and_return(account) 
     <Account(id: integer, title: string, subdomain: string, created_at: datetime, updated_at: datetime) (class)> received :new with unexpected arguments 
     # notice that expected has symbols while the other users strings... 
     expected: ({:title=>"ACME Corp", :subdomain=>"acme1", :users=>{ ... }}) 
       got: ({"title"=>"ACME Corp", "subdomain"=>"acme1", "users"=>{ ... }}) 
    # ./spec/controllers/accounts_controller_spec.rb:34:in `block (3 levels) in <top (required)>' 

我不禁注意到,這段代碼也聞到了一點點。我不知道我是否正在討論這項權利。我是RSpec的新手,如果你能提供一些關於我的努力的反饋,那麼獎勵點數。

回答

3

params散列通常包含字符串而不是符號的鍵。雖然我們使用符號訪問它們,但它是由於它是一個Hash with indifferent access,它並不關心它是否使用字符串或符號進行訪問。

爲了讓您的測試通過,您可以在設置期望值時使用account_attributes哈希上的stringify_keys方法。然後,當Rspec比較散列時,這兩個字符串都是字符串鍵。


現在,關於你問的回顧:實例賬號真的是,你必須在你的控制器的期望?如果您將斷言/期望置於更具體的,外部可見的行爲上,而不是您的對象應使用的每種方法,那麼您的測試將變得不那麼脆弱。

Rails控制器通常易於測試,因爲有許多等效的方法來操作ActiveRecord模型......我通常會盡量使我的控制器儘可能愚蠢,而且我不會單元測試它們,讓它們的行爲由更高級別的集成測試覆蓋。

+0

謝謝你。我這樣做的方式呢?可以嗎? – Mohamad

+0

看看我的編輯 –