我正在尝试测试我的控制器通过请求规范呈现正确的状态代码。此应用程序使用一些带有动态类名的元编程来呈现视图。如何在下面存根渲染调用以返回我的规范所需的正确状态代码?
Rspec Spec Snippet
context 'renders 200' do
let(:provider_slug) { create(:provider, :active).slug }
let(:template) { "providers/v1/#{provider_slug}/new" }
let(:layout) { "providers/v1/#{provider_slug}" }
let(:provider_double) do
instance_double(
ProviderRouter,
valid?: true,
form_model: ProviderFormModel
)
end
before do
allow(ProviderRouter).
to receive(:new).with(version: 'V1', provider_slug: provider_slug).
and_return(provider_double)
allow(described_class).to receive(:render_new_form).and_return(true)
get route
end
it 'true' do
expect(response.status).to be(200)
end
end
控制器代码段
class V1::ProvidersController < ApplicationViewController
before_action :init_provider, :init_form_types, :validate_provider
def new
@provider_form_model = provider_router.form_model.new
render_new_form
end
private
attr_reader :provider_slug, :provider_path, :provider_router, :provider_model
def render_new_form
render template: "providers/v1/#{provider_slug}/new", layout: "providers/v1/#{provider_slug}"
end
针对以下答案进行了更新
context 'renders 200' do
let(:provider_slug) { create(:provider, :active).slug }
let(:provider_double) do
instance_double(
ProviderRouter,
valid?: true,
form_model: ProviderFormModel
)
end
before do
allow(ProviderRouter).
to receive(:new).with(version: 'V1', provider_slug: provider_slug).
and_return(provider_double)
allow(controller).to receive(:provider_slug).and_return(provider_slug)
allow(controller).to receive(:render).and_call_original
allow(controller).to receive(:render).
with(template: "providers/v1/#{provider_slug}/new", layout: "providers/v1/#{provider_slug}") do
controller.render plain: '200 [OK]'
end
get "/v1/providers/#{provider_slug}"
end
it 'true' do
expect(response.status).to be(200)
end
end
答案 0 :(得分:0)
正式的答案是你不应该将它存根,因为你要对被测对象的行为进行存根。
您应该提供provider_slug
用于测试。
从技术上讲,可以这样做:
allow(controller) # controller is the instance of the ProvidersController used under the hood
.to_receive(:render_new_form)
.and_return("some bogus value")
但是这会导致rails尝试渲染默认模板,因为还没有渲染。因此,实际调用render
方法是有帮助的,该方法可以通过以下方式实现:
# we call the render method in our stub and thus have to be able to call the original
allow(controller)
.to receive(:render)
.and_call_original
allow(controller)
.to_receive(:render) # not render_new_form
.with(template: anything, layout: anything) do
controller.render plain: '200 [OK]'
end