我正在測試我的控制器,並且有一個產生AR查詢的字符串: current_user.providers.find(params[:id])
。我需要它返回到我測試的對象,否則,控制器獲取的參考信息與我在spec中的參考信息不同,並且某些存根(如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
作爲有異味的代碼。 另外,我想後面我可能需要用另一個ID調用current_user.providers.find(otherid)
來獲得另一個對象,這樣就不再適合我了。
有什麼辦法可以做得更好嗎?我已經設法避免allow_any_instance_of
,這也被認爲是臭,所以我相信有一種方法可以避免這一點,我只是看不到它。 如果沒有,我至少想知道是否有什麼方法可以將with
添加到receive_message_chain
?
===========
我只是想測試我控制器的方法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'。而且我不想擁有一個像'if Rails.env.test?'這樣的字符串。或者你的意思是我可以用其他方式做到嗎? – Ngoral
您在文章的第一句中引用的控制器方法,我會建議用'Provider.find(params [:id])替換它,因爲它應該像'current_user'一樣工作。如果它爲你產生相同的行爲,那麼你的測試代碼看起來好像更容易運行,因爲方法鏈較少。這可能有助於編輯您的帖子更多的代碼示例,因爲我可以在我的假設中脫穎而出。 – abax
我可以輕鬆地添加更多的代碼示例,只是不知道究竟是什麼。 我試過使用'allow(Provider).to接收(:find).with(provider.id).and_return provider',但由於某種原因,這並不起作用。 – Ngoral