n350071のブログ

主にRubyなフリーランスエンジニア

RSpecのrender_templateでtemplateとlayoutがfalseのテストをしたい

2019-09-07 n350071RSpec

🤔 状況

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=#

      ​ ​

      📚 参考

  • 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