メインコンテンツまでスキップ

beforeafterフック

beforeafterフックを使用して、例の本体が実行される前と/または後に任意のコードを実行します。

(((346f5183361f0fd8)))

beforeafterブロックは以下の順序で呼び出されます。

(((5cb5a53e0e371332)))

単独のbeforeまたはafterフックは、デフォルトで:exampleスコープになります。

beforeafterフックは、実行する例のグループ内に直接定義するか、グローバルなRSpec.configureブロックに定義することができます。ただし、例のステータスはフックに影響しません。

警告: before(:suite)ではインスタンス変数の設定はサポートされていません。

警告: モックはbefore(:example)でのみサポートされています。

警告: aroundフックは、定義されたコンテキストに関係なく、beforeフックの前とafterフックの後に実行されます。

注意: :exampleおよび:contextスコープは、それぞれ:eachおよび:allとしても利用できます。お好みのものを使用してください。

before(:example)ブロックの定義

次の内容で「before_example_spec.rb」という名前のファイルがあるとします。

require "rspec/expectations"

class Thing
def widgets
@widgets ||= []
end
end

RSpec.describe Thing do
before(:example) do
@thing = Thing.new
end

describe "initialized in before(:example)" do
it "has 0 widgets" do
expect(@thing.widgets.count).to eq(0)
end

it "can accept new widgets" do
@thing.widgets << Object.new
end

it "does not share state across examples" do
expect(@thing.widgets.count).to eq(0)
end
end
end

「rspec before_example_spec.rb」と実行すると、

すべての例がパスするはずです。

例グループ内でbefore(:context)ブロックを定義

次の内容で「before_context_spec.rb」という名前のファイルがあるとします。

require "rspec/expectations"

class Thing
def widgets
@widgets ||= []
end
end

RSpec.describe Thing do
before(:context) do
@thing = Thing.new
end

describe "initialized in before(:context)" do
it "has 0 widgets" do
expect(@thing.widgets.count).to eq(0)
end

it "can accept new widgets" do
@thing.widgets << Object.new
end

it "shares state across examples" do
expect(@thing.widgets.count).to eq(1)
end
end
end

「rspec before_context_spec.rb」と実行すると、

すべての例がパスするはずです。

「rspec before_context_spec.rb:15」と実行すると、

すべての例がパスするはずです。

before(:context)ブロックでの失敗

次の内容で「before_context_spec.rb」という名前のファイルがあるとします。

RSpec.describe "an error in before(:context)" do
before(:context) do
raise "oops"
end

it "fails this example" do
end

it "fails this example, too" do
end

after(:context) do
puts "after context ran"
end

describe "nested group" do
it "fails this third example" do
end

it "fails this fourth example" do
end

describe "yet another level deep" do
it "fails this last example" do
end
end
end
end

「rspec before_context_spec.rb --format documentation」と実行すると、

出力に「5 examples, 5 failures」という文言が含まれるはずです。

また、出力には以下の内容が含まれるはずです。

an error in before(:context)
fails this example (FAILED - 1)
fails this example, too (FAILED - 2)
nested group
fails this third example (FAILED - 3)
fails this fourth example (FAILED - 4)
yet another level deep
fails this last example (FAILED - 5)
after context ran

「rspec before_context_spec.rb:9 --format documentation」と実行すると、

出力に「1 example, 1 failure」という文言が含まれるはずです。

また、出力には以下の内容が含まれるはずです。

an error in before(:context)
fails this example, too (FAILED - 1)

after(:context) ブロックでの失敗

以下の内容で "after_context_spec.rb" という名前のファイルがあるとします:

RSpec.describe "an error in after(:context)" do
after(:context) do
raise StandardError.new("Boom!")
end

it "passes this example" do
end

it "passes this example, too" do
end
end

rspec after_context_spec.rb を実行すると、

次のように失敗するはずです:

An error occurred in an `after(:context)` hook.
Failure/Error: raise StandardError.new("Boom!")

StandardError:
Boom!
# ./after_context_spec.rb:3

例内の失敗はフックに影響を与えません

以下の内容で "failure_in_example_spec.rb" という名前のファイルがあるとします:

RSpec.describe "a failing example does not affect hooks" do
before(:context) { puts "before context runs" }
before(:example) { puts "before example runs" }
after(:example) { puts "after example runs" }
after(:context) { puts "after context runs" }

it "fails the example but runs the hooks" do
raise "An Error"
end
end

rspec failure_in_example_spec.rb を実行すると、

次のように失敗するはずです:

before context runs
before example runs
after example runs
Fafter context runs

設定で beforeafter ブロックを定義する

以下の内容で "befores_in_configuration_spec.rb" という名前のファイルがあるとします:

require "rspec/expectations"

RSpec.configure do |config|
config.before(:example) do
@before_example = "before example"
end
config.before(:context) do
@before_context = "before context"
end
end

RSpec.describe "stuff in before blocks" do
describe "with :context" do
it "should be available in the example" do
expect(@before_context).to eq("before context")
end
end
describe "with :example" do
it "should be available in the example" do
expect(@before_example).to eq("before example")
end
end
end

rspec befores_in_configuration_spec.rb を実行すると、

すべての例が成功するはずです。

before/after ブロックは順番に実行されます

以下の内容で "ensure_block_order_spec.rb" という名前のファイルがあるとします:

require "rspec/expectations"

RSpec.describe "before and after callbacks" do
before(:context) do
puts "before context"
end

before(:example) do
puts "before example"
end

before do
puts "also before example but by default"
end

after(:example) do
puts "after example"
end

after do
puts "also after example but by default"
end

after(:context) do
puts "after context"
end

it "gets run in order" do

end
end

rspec --format progress ensure_block_order_spec.rb を実行すると、

出力に次の内容が含まれるはずです:

before context
before example
also before example but by default
also after example but by default
after example
.after context

設定で定義された before/after ブロックは順番に実行されます

以下の内容で "configuration_spec.rb" という名前のファイルがあるとします:

require "rspec/expectations"

RSpec.configure do |config|
config.before(:suite) do
puts "before suite"
end

config.before(:context) do
puts "before context"
end

config.before(:example) do
puts "before example"
end

config.after(:example) do
puts "after example"
end

config.after(:context) do
puts "after context"
end

config.after(:suite) do
puts "after suite"
end
end

RSpec.describe "ignore" do
example "ignore" do
end
end

rspec --format progress configuration_spec.rb を実行すると、

出力に次の内容が含まれるはずです:

before suite
before context
before example
after example
.after context
after suite

before/after コンテキストブロックは一度だけ実行されます

以下の内容で "before_and_after_context_spec.rb" という名前のファイルがあるとします:

RSpec.describe "before and after callbacks" do
before(:context) do
puts "outer before context"
end

example "in outer group" do
end

after(:context) do
puts "outer after context"
end

describe "nested group" do
before(:context) do
puts "inner before context"
end

example "in nested group" do
end

after(:context) do
puts "inner after context"
end
end

end

rspec --format progress before_and_after_context_spec.rb を実行すると、

すべての例が成功するはずです。

また、出力に次の内容が含まれるはずです:

outer before context
.inner before context
.inner after context
outer after context

rspec --format progress before_and_after_context_spec.rb:14 を実行すると、

すべての例が成功するはずです。

また、出力に次の内容が含まれるはずです:

outer before context
inner before context
.inner after context
outer after context

rspec --format progress before_and_after_context_spec.rb:6 を実行すると、

すべての例が成功するはずです。

また、出力に次の内容が含まれるはずです:

outer before context
.outer after context

入れ子の例は外部の before(:context) で設定された状態にアクセスできます

Given ファイル名が "before_context_spec.rb" のファイルがある場合、以下のようになります:

RSpec.describe "something" do
before :context do
@value = 123
end

describe "nested" do
it "access state set in before(:context)" do
expect(@value).to eq(123)
end

describe "nested more deeply" do
it "access state set in before(:context)" do
expect(@value).to eq(123)
end
end
end

describe "nested in parallel" do
it "access state set in before(:context)" do
expect(@value).to eq(123)
end
end
end

When rspec before_context_spec.rb を実行すると、

Then すべての例がパスするはずです。

before/after コンテキストブロックは状態にアクセスできます

Given ファイル名が "before_and_after_context_spec.rb" のファイルがある場合、以下のようになります:

RSpec.describe "before and after callbacks" do
before(:context) do
@outer_state = "set in outer before context"
end

example "in outer group" do
expect(@outer_state).to eq("set in outer before context")
end

describe "nested group" do
before(:context) do
@inner_state = "set in inner before context"
end

example "in nested group" do
expect(@outer_state).to eq("set in outer before context")
expect(@inner_state).to eq("set in inner before context")
end

after(:context) do
expect(@inner_state).to eq("set in inner before context")
end
end

after(:context) do
expect(@outer_state).to eq("set in outer before context")
end
end

When rspec before_and_after_context_spec.rb を実行すると、

Then すべての例がパスするはずです。

before(:example) 内での例外はキャプチャされ、失敗として報告されます

Given ファイル名が "error_in_before_example_spec.rb" のファイルがある場合、以下のようになります:

RSpec.describe "error in before(:example)" do
before(:example) do
raise "this error"
end

it "is reported as failure" do
end
end

When rspec error_in_before_example_spec.rb を実行すると、

Then 出力には "1 example, 1 failure" が含まれるはずです。

And 出力には "this error" が含まれるはずです。