20
21

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Rspecでbeforeを使うと便利です!

Posted at

#はじめに
現在、プログラミングに触れて1ヶ月半ほどになりました。

RSpecで冗長な記述をしたくない。そんなときに使えるのがbeforeです。

今回はbeforeの使い方について自分の理解を深める意味も込めて、説明したいと思います!

#beforeとは?

beforeは

before do
 共通化できる記述
end

とすることでbeforeの後に共通している部分を前もって定義しておくことができます。

#実際に使ってみます。

例えばログインしているユーザーがメッセージを送信できるアプリがあったとして、

コントローラのindexアクションでテストをやってみます。

まず一つが
it "テストしたいこと" do
end

で囲まれる手前で記述する方法です。

下の例をみてください

※説明しやすいようににA~Dで記述しました。また、説明に必要のない記述は全て省いてあります。

describe MessagesController do
  describe "GET #index" do

    context "サインインしてるとき" do
      
      before do
        サインインしてる時の記述
      end

      it " A  " do
        expect(...).to render_template ...
      end

      it "  B  " do
        expect(assigns(...)).to be_a_new(...)
      end

      it "  C  " do
        expect(assigns(...)).to match(...)
      end

      it "  D  " do
        expect(assigns(...)).eq ...
      end
    end

    context "サインインしてないとき" do
      it "  E  " do
        expect(...).to redirect_to (...)
      end
    end
  end
end

A~Dはサインインしているという共通の前提があります。

こういう場合は上のように before do...end の文でサインインしていることをまとめてあげることで、

毎回 it "" do...endの中でサインインをしている記述をする必要がなくなります。

もしbeforeを使わないと・・・

describe MessagesController do
  describe "GET #index" do

    context "サインインしてるとき" do

      it " A  " do
        サインインしてる時の記述
        expect(...).to render_template ...
      end

      it "  B  " do
        サインインしてる時の記述
        expect(assigns(...)).to be_a_new(...)
      end

      it "  C  " do
        サインインしてる時の記述
        expect(assigns(...)).to match(...)
      end

      it "  D  " do
        サインインしてる時の記述
        expect(assigns(...)).to eq ...
      end
    end

    context "サインインしてないとき" do
      it "  E  " do
        expect(...).to redirect_to (...)
      end
    end
  end
end

4回も記述することになってしまいます。

これはちょっと見づらくて長い記述になってしまいます。

また、context...endで囲まれる外側でも使用可能です。

例えばcreateアクションでメッセージの保存できたかをテストしたい時、

メッセージが保存された時も、保存されなかった時もユーザーはサインインしていることは前提になっています。

なので以下のように書くことができます。

describe MessagesController do
  describe "POST #create" do

    before do
      サインインしてる時の記述
    end

    context "メッセージが保存された時" do
      it "  A  " do
        expect(...).to redirect_to (...)
      end

      it "  B  " do
        expect(...).to match(...)
      end
    end

    context "メッセージが保存されなかった時" do

      it "  C  " do
        expect(...).to render_template ...
      end

      it "  D  " do
        expect(...).to match(...)
      end
    end

      it "  E  " do
        expect{assigns(...)}.to change(...)
      end
  end
end

これもbeforeを使わないと大変なことになります。

describe MessagesController do
  describe "POST #create" do

    context "メッセージが保存された時" do
      it "  A  " do
        expect(...).to redirect_to (...)
      サインインしてる時の記述
      end

      it "  B  " do
        expect(...).to match(...)
      サインインしてる時の記述
      end
    end

    context "メッセージが保存されなかった時" do

      it "  C  " do
        expect(...).to render_template ...
      サインインしてる時の記述
      end

      it "  D  " do
        expect(...).to match(...)
      サインインしてる時の記述
      end
    end

      it "  E  " do
        expect{assigns(...)}.to change(...)
      サインインしてる時の記述
      end
  end
end

今回だと5回も同じ記述が登場してしまいます。

これはあまりにも長すぎるので、beforeでまとめましょう。

#注意点

beforeの位置によっては意味合いが変わってきます。

自分が書いたbeforeはどこまで適用されるのか、これを意識していくことが

使う上では重要になってきますので、しょうもないエラーを出さないためにも

このあたりはしっかりやっていきたいです!

20
21
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
20
21

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?