私は私のコントローラをテストしていとARクエリ生成文字列があります: current_user.providers.find(params[:id])
が。テストするオブジェクトを正確に返す必要があります。それ以外の場合は、コントローラーが私の仕様とは異なるリファレンスを取得し、allow(provider).to receive(:recreate)
のようなスタブが機能しません。receive_message_chainと臭いコード
これを行うには、receive_message_chain
を次のように使用してください。 allow(provider.user).to receive_message_chain(:providers, :find => provider)
しかし、rspecのドキュメントsaysを使用して、receive_message_chain
のコードを使用することをお勧めします。 さらに、current_user.providers.find(otherid)
に別のIDを付けて別のオブジェクトを取得する必要があるかもしれないと思うので、それはもう役に立たないでしょう。
は、より良い、それを行うための方法はありますか?私はすでにallow_any_instance_of
を避けることができました。それもまた臭いと考えられていますので、これも避ける方法があると信じています。私はそれを見ることはできません。 何があるなら、私は少なくともreceive_message_chain
にwith
のようなものを追加する方法はありませんかしら?
===========
私はちょうど私のコントローラのupdate
メソッドをテストしようとしています。
# app/controllers/restream/facebooks_controller.rb
class Restream::FacebooksController < Restream::BaseController
def update
current_user.providers.find(params[:id])
if @fb.update_attributes(facebook_params)
if event_changed?
@fb.recreate
else
@fb.update
end
redirect_to restreams_path
else
render 'edit'
end
end
end
#spec/controllers/restream/facebooks_controller_spec.rb
require 'rails_helper'
describe Restream::FacebooksController do
let!(:facebook) { create(:restream_facebook) }
let!(:restream) { facebook.restream }
before do
login(restream.user)
end
describe '#update' do
let!(:params_hash) { {
:title => facebook.title,
:privacy => facebook.privacy,
:destination => facebook.destination,
:destination_id => facebook.destination_id,
:description => facebook.description
} }
let!(:request_hash) { {
:restream_facebook => params_hash,
:id => facebook.id
} }
before do
allow(facebook.user).
to receive_message_chain(:providers, :find => facebook)
allow(facebook).to receive(:update)
allow(facebook).to receive(:recreate)
end
context 'updates' do
it 'title' do
params_hash[:title] = SecureRandom.hex(2)
post :update, request_hash
expect(facebook.reload.title).to eq params_hash[:title]
end
end
end
end
私は永久に 'current_user'を削除することはできません。そして、私は 'Rails.env.test? 'のような文字列も望んでいません。それとも私は他のやり方でやることができるのですか?それはcurrent_user'がそれに上のタック '持つと同じように動作するはずのように:あなたはあなたのポストの最初の文で参照 – Ngoral
コントローラのメソッドは、私は' Provider.find([ID]のparams)で置き換えることをお勧め。それが同じ振る舞いを生み出すならば、メソッド連鎖が少なくて済むので、テストコードが簡単に実行できるようです。それはおそらく、私の前提にとらわれている可能性があるので、より多くのコード例であなたの投稿を編集するのに役立つだろう。 – abax
私は簡単にコードサンプルを追加することができますが、ちょうど正確には分かりません。 私は 'allow(Provider).to receive(:find).with(provider.id).and_return provider'を使用しようとしましたが、それは何らかの理由で動作しませんでした。 – Ngoral