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
以上。