#はじめに
現在、プログラミングに触れて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はどこまで適用されるのか、これを意識していくことが
使う上では重要になってきますので、しょうもないエラーを出さないためにも
このあたりはしっかりやっていきたいです!