RSpecのrender_templateでtemplateとlayoutがfalseのテストをしたい
🤔 状況
hoges_controller
以下のようになることをテストしたい
-
期限切れであれば
- view: expired
- layout: なし
-
さもなくば(暗黙的に)以下である
- view:
views/hoges/show.html.erb
-
layout:
layouts/application.html.erb
def show return render :expired, layout: false if @hoge.expired? end
👍 方法
subject { get :show, id: hoge.id } context 'expired' do let(:hoge) { create(:hoge, :expired) } it do expect(subject).to be_success expect(subject).to render_template(template: :expired, layout: []) end end context 'valid' do let(:hoge) { create(:hoge, :valid) } it do expect(subject).to be_success expect(subject).to render_template(template: :show, layout: 'layouts/application') end end
👎 間違ったやり方
以下のように、templateやlayoutを指定せずに書くと、
expect(subject).to render_template(:show, 'layouts/application')
マッチャに正しくセットされなくなってしまい、templateさえ合っていれば通ってしまうテストになってしまい、 エラーになるべきテストをエラーにできない(falseNegativeな)テストになってしまうので注意してください。
[2] render_template :show, 'layouts/application' => #<RSpec::Rails::Matchers::RenderTemplate::RenderTemplateMatcher:0x00007ffd90dba7fc @expected="show", @message="layouts/application", 👎 @redirect_is=nil, @scope=#
📚 参考
- view:
- ruby on rails - Rspec test to render no layout - Stack Overflow
- Method: Spec::Rails::Matchers#render_template — Documentation for rspec-rails (1.3.4)
hoges_controller_spec.rb