0

ネストされたリソースを使用するコントローラーの作成アクションをテストするためにこれを書きました。関連付けのある Account モデルがありhas_many :usersます。サインアップすると、1 人のユーザーのアカウントが作成されます。

  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

これは私が得ている失敗の出力です。expected と got の違いに注意してください。文字列を取得している間にシンボルを期待していました。

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 を初めて使用するので、私の努力についてフィードバックを提供していただければボーナス ポイントを提供できます。

4

1 に答える 1

3

paramsハッシュには通常、記号ではなく文字列であるキーが含まれます。シンボルを使用してそれらにアクセスしますが、それは、文字列またはシンボルを使用してアクセスするかどうかを気にしない、無差別アクセスのハッシュであるという事実によるものです。

テストに合格するには、期待値を設定するときstringify_keysにハッシュでメソッドを使用できます。account_attributes次に、Rspec がハッシュを比較すると、両方が文字列キーになります。


さて、あなたが尋ねたレビューについて:アカウントをインスタンス化することは、あなたのコントローラーに本当に期待されていることですか? オブジェクトが使用する必要がある各メソッドではなく、より具体的で外部から見える動作にアサーション/期待を配置すると、テストの脆弱性が軽減されます。

ActiveRecordモデルを操作するための同等の方法がたくさんあるため、Railsコントローラーは一般的にテストが脆弱です...私は通常、コントローラーをできるだけ馬鹿げたものにしようとします。高レベルの統合テスト。

于 2012-10-06T14:54:34.583 に答える