LoginSignup
42
19

More than 5 years have passed since last update.

rspecでis_expectedにブロックを渡す

Last updated at Posted at 2017-03-29

rspecでchangeなどを使う場合、ブロックを渡さないといけません。

spec/models/hoge_spec.rb
describe 'hoge' do
  it{ expect{ hoge }.to change{ Hoge.count }.by(1) }
end

なので、subject/is_expectedを使いたい場合は少し気をつけないといけません。

spec/models/hoge_spec.rb
describe 'hoge' do
  subject { hoge }
  it{ is_expected.to change{ Hoge.count }.by(1) }
end

#=> Failure/Error: is_expected.to change{ Hoge.count }.by(1)
#     expected result to have changed by 1, but was not given a block

上記の通り、subjectにブロックを渡していないのでエラーになります。

そのままブロックを渡すパターン

とりあえず、subjectにそのままブロックを渡せば要件は満たせます。

spec/models/hoge_spec.rb
# Proc.newで渡す場合
describe 'hoge' do
  subject{ Proc.new { hoge } }
  it{ is_expected.to change{ Hoge.count }.by(1) }
end

# lambdaで渡す場合
describe 'hoge' do
  subject{ ->{ hoge } }
  it{ is_expected.to change{ Hoge.count }.by(1) }
end

拡張するパターン

ただ、拡張してメソッド追加したほうがいろいろ捗りそうです。

spec/rails_helper.rb
module IsExpectedBlock
  def is_expected_block
    expect { subject }
  end
end

RSpec.configure do |c|
  c.include IsExpectedBlock
end
spec/models/hoge_spec.rb
# subjectにはブロックを渡していない
describe 'hoge' do
  subject{ hoge }
  it{ is_expected_block.to change{ Hoge.count }.by(1) }
end

以上。

参考

42
19
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
42
19