Re:ゼロから始めるNo Error No Life

ぷろぐらみんぐ的なことと趣味的な日常を少々

Rspecに初心者が挑む②

今回は、共通化

いきなりですが

describe 'GET #index' do
  context 'http_status_test'
    it {expect(response).to render_template :index}    
    it {expect(response).to have_http_status(302)}
  end
end

#もしくは
describe 'GET #index' do
  context 'http_status_test'
    it '' do
      expect(response).to redirect_to home_index_path   
      expect(response).to have_http_status(302)
    end
  end
end

みたいなのがあったとします。冗長っすよね。共通化したいわーってなりますよね

なので以下の様に書いてみます。

shared_examples "common_test_logic" do | mode,  template_or_path, status |
    if mode == 'redirect'
        it {expect(response).to redirect_to template_or_path}
    elsif mode == 'render'
        it {expect(response).to render_template template_or_path} if template_or_path
    end
    it {expect(response).to have_http_status(status)}
end

綺麗なコードではないですが、自分にとってここはスタートなので晒します。

きっと半年後とかに「くそコードなおい!!」ってなっていることを祈ります。

呼び出し方法は以下

it_behaves_like "common_test_logic","redirect", '/home', 302

一つのファイルに書いてもいいのですが

なんなら他のspecファイルでも使いたいではないか。

と思うのでこれを

spec/support以下に配置します。

上記コードの説明を軽くしますと

specファイルってあくまでもrb拡張子がついていることからわかるようにrubyの構文がかけます

なので引数でifの条件分岐で実行内容を変えてます

難点なのがit句で全部を囲った際、挙動が期待通りにならなかったこと

なのでそれぞれをit句で囲いました

その結果factoryのcreateメソッドがit句が実行されるたびに動くのが困りものです。

データの定義を変えるべきなのか

shared_exampleの使い方を変えるべきなのか。。。

ちなみに条件分岐をしない場合は、it句で全文を囲ってしまってます。

context部分をごそっと入れてしまうことも可能です。 細かくは以下

rspecの公式ガイドをはっとくので覗いて見えてはどうでしょうか? ※全文英語です

www.relishapp.com