contexts * Use let and before * Use subject and named subject * Reserved DRY * Expect change * Should not update context value * Set all significant fields on test data * Write expectations at a high level * Should not use "should" in our example names
error when already reserved' do # ... end it 'reserves the book when the book is available' do # ... end end end Describe and context RSpec.describe Book do describe '#reserve' do context 'when already reserved' do it 'raises already reserved error' do # ... end end context 'the book is available' do it 'reserves the book' do # ... end end end end Better /PUGood
do let(:reserved) { true } context 'when the users reservation limit is exceeded' do let(:exceeded) { true } # ... end context 'when the users reservation limit is not exceeded' do let(:exceeded) { false } # ... end end context 'the book is available' do let(:reserved) { false } context 'when the users reservation limit is exceeded' do let(:exceeded) { true } # ... end context 'when the users reservation limit is not exceeded' do let(:exceeded) { false } # ... end end end end Use single-level contexts RSpec.describe Book do describe '#reserve' do context 'when already reserved and the user reservation limit is exceeded' do let(:reserved) { true } let(:exceeded) { true } # ... end context 'when already reserved and the users reservation limit is not exceeded' do let(:reserved) { true } let(:exceeded) { false } # ... end context 'the book is available and the user reservation limit is exceeded' do let(:reserved) { false } let(:exceeded) { true } # ... end context 'the book is available and the user has enough reservation limit' do let(:reserved) { false } let(:exceeded) { false } # ... end end end Better /PUGood
do let(:reserved) { true } context 'when the users reservation limit is exceeded' do let(:exceeded) { true } # ... end context 'when the users reservation limit is not exceeded' do let(:exceeded) { false } # ... end end context 'the book is available' do let(:reserved) { false } context 'when the users reservation limit is exceeded' do let(:exceeded) { true } # ... end context 'when the users reservation limit is not exceeded' do let(:exceeded) { false } # ... end end end end Use single-level contexts RSpec.describe Book do describe '#reserve' do context 'when already reserved and the user reservation limit is exceeded' do let(:reserved) { true } let(:exceeded) { true } # ... end context 'when already reserved and the users reservation limit is not exceeded' do let(:reserved) { true } let(:exceeded) { false } # ... end context 'the book is available and the user reservation limit is exceeded' do let(:reserved) { false } let(:exceeded) { true } # ... end context 'the book is available and the user has enough reservation limit' do let(:reserved) { false } let(:exceeded) { false } # ... end end end Better /PUGood RSpec.describe Book do describe '#reserve' do context 'when already reserved' do let(:reserved) { true } context 'when the users reservation limit is exceeded' do let(:exceeded) { true } # ... end end end /PUGood
do let(:reserved) { true } context 'when the users reservation limit is exceeded' do let(:exceeded) { true } # ... end context 'when the users reservation limit is not exceeded' do let(:exceeded) { false } # ... end end context 'the book is available' do let(:reserved) { false } context 'when the users reservation limit is exceeded' do let(:exceeded) { true } # ... end context 'when the users reservation limit is not exceeded' do let(:exceeded) { false } # ... end end end end Use single-level contexts RSpec.describe Book do describe '#reserve' do context 'when already reserved and the user reservation limit is exceeded' do let(:reserved) { true } let(:exceeded) { true } # ... end context 'when already reserved and the users reservation limit is not exceeded' do let(:reserved) { true } let(:exceeded) { false } # ... end context 'the book is available and the user reservation limit is exceeded' do let(:reserved) { false } let(:exceeded) { true } # ... end context 'the book is available and the user has enough reservation limit' do let(:reserved) { false } let(:exceeded) { false } # ... end end end Better /PUGood RSpec.describe Book do describe '#reserve' do context 'when already reserved and the user reservation limit is exceeded' do let(:reserved) { true } let(:exceeded) { true } # ... end end end #FUUFS
do let(:reserved) { true } context 'when the users reservation limit is exceeded' do let(:exceeded) { true } # ... end context 'when the users reservation limit is not exceeded' do let(:exceeded) { false } # ... end end context 'the book is available' do let(:reserved) { false } context 'when the users reservation limit is exceeded' do let(:exceeded) { true } # ... end context 'when the users reservation limit is not exceeded' do let(:exceeded) { false } # ... end end end end Use single-level contexts RSpec.describe Book do describe '#reserve' do context 'when already reserved and the user reservation limit is exceeded' do let(:reserved) { true } let(:exceeded) { true } # ... end context 'when already reserved and the users reservation limit is not exceeded' do let(:reserved) { true } let(:exceeded) { false } # ... end context 'the book is available and the user reservation limit is exceeded' do let(:reserved) { false } let(:exceeded) { true } # ... end context 'the book is available and the user has enough reservation limit' do let(:reserved) { false } let(:exceeded) { false } # ... end end end Better /PUGood RSpec.describe Book do describe '#reserve' do context 'when already reserved and the user reservation limit is exceeded' do let(:reserved) { true } let(:exceeded) { true } # ... end context 'when already reserved and the users reservation limit is not exceeded' do let(:reserved) { true } let(:exceeded) { false } # ... end end end #FUUFS
'when the book is already reserved' do it 'returns falsey value' do reserved = true book = Book.new(reserved: reserved) book.reserve expect(book.reserved).to be_falsey end end end end # Case 2 RSpec.describe Book do describe '#reserve' do context 'when the book is already reserved' do before do @reserved = true @book = Book.new(reserved: reserved) @book.reserve end it 'returns falsey value' do expect(@book.reserve).to be_falsey end end end end Use let and before RSpec.describe Book do describe '#reserve' do subject { book.reserve } let(:book) { Book.new(reserved: reserved) } context 'when the book is already reserved' do let(:reserved) { true } it 'returns falsey value' do is_expected.to be_falsey end end end end Better /PUGood
'when the book is already reserved' do it 'returns falsey value' do reserved = true book = Book.new(reserved: reserved) book.reserve expect(book.reserved).to be_falsey end end end end # Case 2 RSpec.describe Book do describe '#reserve' do context 'when the book is already reserved' do before do @reserved = true @book = Book.new(reserved: reserved) @book.reserve end it 'returns falsey value' do expect(@book.reserve).to be_falsey end end end end Use let and before RSpec.describe Book do describe '#reserve' do subject { book.reserve } let(:book) { Book.new(reserved: reserved) } context 'when the book is already reserved' do let(:reserved) { true } it 'returns falsey value' do is_expected.to be_falsey end end end end Better /PUGood # Case 1 RSpec.describe Book do describe '#reserve' do context 'when the book is already reserved' do it 'returns falsey value' do reserved = true book = Book.new(reserved: reserved) book.reserve expect(book.reserved).to be_falsey end end end end /PUGood DPOUFYU͕Կ͔͕Θ͔ΓͮΒ͍
'when the book is already reserved' do it 'returns falsey value' do reserved = true book = Book.new(reserved: reserved) book.reserve expect(book.reserved).to be_falsey end end end end # Case 2 RSpec.describe Book do describe '#reserve' do context 'when the book is already reserved' do before do @reserved = true @book = Book.new(reserved: reserved) @book.reserve end it 'returns falsey value' do expect(@book.reserve).to be_falsey end end end end Use let and before RSpec.describe Book do describe '#reserve' do subject { book.reserve } let(:book) { Book.new(reserved: reserved) } context 'when the book is already reserved' do let(:reserved) { true } it 'returns falsey value' do is_expected.to be_falsey end end end end Better /PUGood /PUGood DPOUFYU͕Կ͔͕Θ͔ΓͮΒ͍ # Case 1 RSpec.describe Book do describe '#reserve' do context 'when the book is already reserved' do it 'returns falsey value' do reserved = true book = Book.new(reserved: reserved) book.reserve expect(book.reserved).to be_falsey end end end end ͕͜͜DPOUFYU
'when the book is already reserved' do it 'returns falsey value' do reserved = true book = Book.new(reserved: reserved) book.reserve expect(book.reserved).to be_falsey end end end end # Case 2 RSpec.describe Book do describe '#reserve' do context 'when the book is already reserved' do before do @reserved = true @book = Book.new(reserved: reserved) @book.reserve end it 'returns falsey value' do expect(@book.reserve).to be_falsey end end end end Use let and before RSpec.describe Book do describe '#reserve' do subject { book.reserve } let(:book) { Book.new(reserved: reserved) } context 'when the book is already reserved' do let(:reserved) { true } it 'returns falsey value' do is_expected.to be_falsey end end end end Better /PUGood # Case 2 RSpec.describe Book do describe '#reserve' do context 'when the book is already reserved' do before do @reserved = true @book = Book.new(reserved: reserved) @book.reserve end it 'returns falsey value' do expect(@book.reserve).to be_falsey end end end end /PUGood *OTUBODFWBSJBCMFΛΘͳ͍
'when the book is already reserved' do it 'returns falsey value' do reserved = true book = Book.new(reserved: reserved) book.reserve expect(book.reserved).to be_falsey end end end end # Case 2 RSpec.describe Book do describe '#reserve' do context 'when the book is already reserved' do before do @reserved = true @book = Book.new(reserved: reserved) @book.reserve end it 'returns falsey value' do expect(@book.reserve).to be_falsey end end end end Use let and before RSpec.describe Book do describe '#reserve' do subject { book.reserve } let(:book) { Book.new(reserved: reserved) } context 'when the book is already reserved' do let(:reserved) { true } it 'returns falsey value' do is_expected.to be_falsey end end end end Better /PUGood /PUGood ΠϯελϯεมΛΘͳ͍ # Case 2 RSpec.describe Book do describe '#reserve' do context 'when the book is already reserved' do before do @reserved = true @book = Book.new(reserved: reserved) @book.reserve end it 'returns falsey value' do expect(@book.reserve).to be_falsey end end end end FYBNQMFຖͰݺΕͯ͠·͏ ϩʔΧϧมͱͷ۠ผ͕ ͘͠ͳΔ
is already reserved' do it 'returns falsey value' do reserved = true book = Book.new(reserved: reserved) book.reserve expect(book.reserved).to be_truthy end end end end RSpec.describe Book do describe '#reserve' do before do @reserved = true @book = Book.new(reserved: reserved) @book.reserve end it 'returns falsey value' do expect(@book.reserve).to be_falsey end end end Use let and before RSpec.describe Book do describe '#reserve' do context 'when already reserved and the user reservation limit is exceeded' do let(:reserved) { true } let(:exceeded) { true } # ... end context 'when already reserved and the users reservation limit is not exceeded' do let(:reserved) { true } let(:exceeded) { false } # ... end context 'the book is available and the user reservation limit is exceeded' do let(:reserved) { false } let(:exceeded) { true } # ... end context 'the book is available and the user has enough reservation limit' do let(:reserved) { false } let(:exceeded) { false } # ... end end end Better /PUGood RSpec.describe Book do describe '#reserve' do subject { book.reserve } let(:book) { Book.new(reserved: reserved) } context 'when the book is already reserved' do let(:reserved) { true } it 'returns falsey value' do is_expected.to be_falsey end end end end #FUUFS
is already reserved' do it 'returns falsey value' do reserved = true book = Book.new(reserved: reserved) book.reserve expect(book.reserved).to be_truthy end end end end RSpec.describe Book do describe '#reserve' do before do @reserved = true @book = Book.new(reserved: reserved) @book.reserve end it 'returns falsey value' do expect(@book.reserve).to be_falsey end end end Use let and before RSpec.describe Book do describe '#reserve' do context 'when already reserved and the user reservation limit is exceeded' do let(:reserved) { true } let(:exceeded) { true } # ... end context 'when already reserved and the users reservation limit is not exceeded' do let(:reserved) { true } let(:exceeded) { false } # ... end context 'the book is available and the user reservation limit is exceeded' do let(:reserved) { false } let(:exceeded) { true } # ... end context 'the book is available and the user has enough reservation limit' do let(:reserved) { false } let(:exceeded) { false } # ... end end end Better /PUGood #FUUFS RSpec.describe Book do describe '#reserve' do subject { book.reserve } let(:book) { Book.new(reserved: reserved) } context 'when the book is already reserved' do let(:reserved) { true } it 'returns falsey value' do is_expected.to be_falsey end end end end DPOUFYUͱMFU͕ରԠ͍ͯͯ͠ ಡΈ͍͢
} let(:user) { User.new } it 'returns truthy value' do expect(book.reserve(user)).to be_truthy end it 'reserved user returns correct user' do book.reserve(user) expect(book.reserved_user).to eq user end end end Use subject and named subject RSpec.describe Book do describe '#reserve' do subject(:reserve_book) { book.reserve } let(:book) { Book.new(reserved: false) } let(:user) { User.new } it 'returns truthy value' do is_expected.to be_truthy end it 'reserved user returns correct user' do reserve_book expect(book.reserved_user).to eq user end it 'number of books that the user reserved increases by 1' do expect { reserve_book }.to change { user.reserved_books.count }.by(1) end end end Better /PUGood
} let(:user) { User.new } it 'returns truthy value' do expect(book.reserve(user)).to be_truthy end it 'reserved user returns correct user' do book.reserve(user) expect(book.reserved_user).to eq user end end end Use subject and named subject RSpec.describe Book do describe '#reserve' do subject(:reserve_book) { book.reserve } let(:book) { Book.new(reserved: false) } let(:user) { User.new } it 'returns truthy value' do is_expected.to be_truthy end it 'reserved user returns correct user' do reserve_book expect(book.reserved_user).to eq user end it 'number of books that the user reserved increases by 1' do expect { reserve_book }.to change { user.reserved_books.count }.by(1) end end end Better /PUGood /PUGood ςετओମ͕Θ͔ΓͮΒ͍ RSpec.describe Book do describe '#reserve' do let(:book) { Book.new(reserved: false) } let(:user) { User.new } it 'returns truthy value' do expect(book.reserve(user)).to be_truthy end it 'reserved user returns correct user' do book.reserve(user) expect(book.reserved_user).to eq user end end end
} let(:user) { User.new } it 'returns truthy value' do expect(book.reserve(user)).to be_truthy end it 'reserved user returns correct user' do book.reserve(user) expect(book.reserved_user).to eq user end end end Use subject and named subject RSpec.describe Book do describe '#reserve' do subject(:reserve_book) { book.reserve } let(:book) { Book.new(reserved: false) } let(:user) { User.new } it 'returns truthy value' do is_expected.to be_truthy end it 'reserved user returns correct user' do reserve_book expect(book.reserved_user).to eq user end it 'number of books that the user reserved increases by 1' do expect { reserve_book }.to change { user.reserved_books.count }.by(1) end end end Better /PUGood #FUUFS RSpec.describe Book do describe '#reserve' do subject { book.reserve } let(:book) { Book.new(reserved: false) } let(:user) { User.new } it 'returns truthy value' do is_expected.to be_truthy end it 'reserved user returns correct user' do subject expect(book.reserved_user).to eq user end end end ςετओମ͕໌͔֬ͭ%3:
} let(:user) { User.new } it 'returns truthy value' do expect(book.reserve(user)).to be_truthy end it 'reserved user returns correct user' do book.reserve(user) expect(book.reserved_user).to eq user end end end Use subject and named subject RSpec.describe Book do describe '#reserve' do subject(:reserve_book) { book.reserve } let(:book) { Book.new(reserved: false) } let(:user) { User.new } it 'returns truthy value' do is_expected.to be_truthy end it 'reserved user returns correct user' do reserve_book expect(book.reserved_user).to eq user end it 'number of books that the user reserved increases by 1' do expect { reserve_book }.to change { user.reserved_books.count }.by(1) end end end Better /PUGood #FUUFS✨ RSpec.describe Book do describe '#reserve' do subject(:reserve_book) { book.reserve } let(:book) { Book.new(reserved: false) } let(:user) { User.new } it 'reserved user returns correct user' do reserve_book expect(book.reserved_user).to eq user end end end ओޠ͕ԿΛҙຯ͢Δͷ͔͕໌֬ʹͳΔ
} let(:user) { User.new } it 'returns truthy value' do expect(book.reserve(user)).to be_truthy end it 'reserved user returns correct user' do book.reserve(user) expect(book.reserved_user).to eq user end end end Use subject and named subject RSpec.describe Book do describe '#reserve' do subject(:reserve_book) { book.reserve } let(:book) { Book.new(reserved: false) } let(:user) { User.new } it 'returns truthy value' do is_expected.to be_truthy end it 'reserved user returns correct user' do reserve_book expect(book.reserved_user).to eq user end it 'number of books that the user reserved increases by 1' do expect { reserve_book }.to change { user.reserved_books.count }.by(1) end end end Better /PUGood #FUUFS✨ DIBOHFFYQFDUBUJPOಛʹݟ͍͢ RSpec.describe Book do describe '#reserve' do subject(:reserve_book) { book.reserve } let(:book) { Book.new(reserved: false) } let(:user) { User.new } it 'number of books that the user reserved increases by 1' do expect { reserve_book }.to change { user.reserved_books.count }.by(1) end end end
decrease remaining by -#{decrease_by}" do expect { reserve_book }.to change { user.remaining_count }.by(-decrease_by) expect(book.reserved_user).to eq user expect(book.reservation.due_date.present?).to be has_due_date end end RSpec.describe Book do describe '#reserve' do subject(:reserve_book) { book.reserve } let(:book) { Book.new } context 'when user has admin role' do let(:user) { User.new(role: [:admin]) } it_bahaves_like "reservation", decrease_by: 0, has_due_date: false end context 'when user has normal role' do let(:user) { User.new(role: [:normal]) } it_bahaves_like "reservation", decrease_by: 1, has_due_date: true end end end Reserved DRY RSpec.describe Book do describe '#reserve' do subject(:reserve_book) { book.reserve } let(:book) { Book.new } context 'when user has admin role' do let(:user) { User.new(role: [:admin]) } it "reserve and decrease remaining count and has no due date" do expect { reserve_book }.not_to change { user.remaining_count } expect(book.reserved_user).to eq user expect(book.reservation.due_date.present?).to be_falsey end end context 'when user has normal role' do let(:user) { User.new(role: [:normal]) } it "reserve and decrease remaining count and has no due date" do expect { reserve_book }.to change { user.remaining_count }.by(1) expect(book.reserved_user).to eq user expect(book.reservation.due_date.present?).to be_truthy end end end end Better /PUGood
decrease remaining by -#{decrease_by}" do expect { reserve_book }.to change { user.remaining_count }.by(-decrease_by) expect(book.reserved_user).to eq user expect(book.reservation.due_date.present?).to be has_due_date end end RSpec.describe Book do describe '#reserve' do subject(:reserve_book) { book.reserve } let(:book) { Book.new } context 'when user has admin role' do let(:user) { User.new(role: [:admin]) } it_bahaves_like "reservation", decrease_by: 0, has_due_date: false end context 'when user has normal role' do let(:user) { User.new(role: [:normal]) } it_bahaves_like "reservation", decrease_by: 1, has_due_date: true end end end Reserved DRY RSpec.describe Book do describe '#reserve' do subject(:reserve_book) { book.reserve } let(:book) { Book.new } context 'when user has admin role' do let(:user) { User.new(role: [:admin]) } it "reserve and decrease remaining count and has no due date" do expect { reserve_book }.not_to change { user.remaining_count } expect(book.reserved_user).to eq user expect(book.reservation.due_date.present?).to be_falsey end end context 'when user has normal role' do let(:user) { User.new(role: [:normal]) } it "reserve and decrease remaining count and has no due date" do expect { reserve_book }.to change { user.remaining_count }.by(1) expect(book.reserved_user).to eq user expect(book.reservation.due_date.present?).to be_truthy end end end end Better /PUGood /PUGood ඞཁͳҾɺ͕݅Θ͔ΓͮΒ͍ RSpec.shared_examples 'reservation' do |decrease_by:, has_due_date:| it "reserve the book and decrease remaining by -#{decrease_by}" do expect { reserve_book }.to change { user.remaining_count }.by(-decrease_by) expect(book.reserved_user).to eq user expect(book.reservation.due_date.present?).to be has_due_date end end
decrease remaining by -#{decrease_by}" do expect { reserve_book }.to change { user.remaining_count }.by(-decrease_by) expect(book.reserved_user).to eq user expect(book.reservation.due_date.present?).to be has_due_date end end RSpec.describe Book do describe '#reserve' do subject(:reserve_book) { book.reserve } let(:book) { Book.new } context 'when user has admin role' do let(:user) { User.new(role: [:admin]) } it_bahaves_like "reservation", decrease_by: 0, has_due_date: false end context 'when user has normal role' do let(:user) { User.new(role: [:normal]) } it_bahaves_like "reservation", decrease_by: 1, has_due_date: true end end end Reserved DRY RSpec.describe Book do describe '#reserve' do subject(:reserve_book) { book.reserve } let(:book) { Book.new } context 'when user has admin role' do let(:user) { User.new(role: [:admin]) } it "reserve and decrease remaining count and has no due date" do expect { reserve_book }.not_to change { user.remaining_count } expect(book.reserved_user).to eq user expect(book.reservation.due_date.present?).to be_falsey end end context 'when user has normal role' do let(:user) { User.new(role: [:normal]) } it "reserve and decrease remaining count and has no due date" do expect { reserve_book }.to change { user.remaining_count }.by(1) expect(book.reserved_user).to eq user expect(book.reservation.due_date.present?).to be_truthy end end end end Better /PUGood /PUGood ඞཁͳҾɺ͕݅Θ͔ΓͮΒ͍ RSpec.shared_examples 'reservation' do |decrease_by:, has_due_date:| it "reserve the book and decrease remaining by -#{decrease_by}" do expect { reserve_book }.to change { user.remaining_count }.by(-decrease_by) expect(book.reserved_user).to eq user expect(book.reservation.due_date.present?).to be has_due_date end end
decrease remaining by -#{decrease_by}" do expect { reserve_book }.to change { user.remaining_count }.by(-decrease_by) expect(book.reserved_user).to eq user expect(book.reservation.due_date.present?).to be has_due_date end end RSpec.describe Book do describe '#reserve' do subject(:reserve_book) { book.reserve } let(:book) { Book.new } context 'when user has admin role' do let(:user) { User.new(role: [:admin]) } it_bahaves_like "reservation", decrease_by: 0, has_due_date: false end context 'when user has normal role' do let(:user) { User.new(role: [:normal]) } it_bahaves_like "reservation", decrease_by: 1, has_due_date: true end end end Reserved DRY RSpec.describe Book do describe '#reserve' do subject(:reserve_book) { book.reserve } let(:book) { Book.new } context 'when user has admin role' do let(:user) { User.new(role: [:admin]) } it "reserve and decrease remaining count and has no due date" do expect { reserve_book }.not_to change { user.remaining_count } expect(book.reserved_user).to eq user expect(book.reservation.due_date.present?).to be_falsey end end context 'when user has normal role' do let(:user) { User.new(role: [:normal]) } it "reserve and decrease remaining count and has no due date" do expect { reserve_book }.to change { user.remaining_count }.by(1) expect(book.reserved_user).to eq user expect(book.reservation.due_date.present?).to be_truthy end end end end Better /PUGood /PUGood ඞཁͳҾɺ͕݅Θ͔ΓͮΒ͍ RSpec.describe Book do describe '#reserve' do subject(:reserve_book) { book.reserve } let(:book) { Book.new } context 'when user has admin role' do let(:user) { User.new(role: [:admin]) } it_bahaves_like "reservation", decrease_by: 0, has_due_date: false end context 'when user has normal role' do let(:user) { User.new(role: [:normal]) } it_bahaves_like "reservation", decrease_by: 1, has_due_date: true end end end
decrease remaining by -#{decrease_by}" do expect { reserve_book }.to change { user.remaining_count }.by(-decrease_by) expect(book.reserved_user).to eq user expect(book.reservation.due_date.present?).to be has_due_date end end RSpec.describe Book do describe '#reserve' do subject(:reserve_book) { book.reserve } let(:book) { Book.new } context 'when user has admin role' do let(:user) { User.new(role: [:admin]) } it_bahaves_like "reservation", decrease_by: 0, has_due_date: false end context 'when user has normal role' do let(:user) { User.new(role: [:normal]) } it_bahaves_like "reservation", decrease_by: 1, has_due_date: true end end end Reserved DRY RSpec.describe Book do describe '#reserve' do subject(:reserve_book) { book.reserve } let(:book) { Book.new } context 'when user has admin role' do let(:user) { User.new(role: [:admin]) } it "reserve and decrease remaining count and has no due date" do expect { reserve_book }.not_to change { user.remaining_count } expect(book.reserved_user).to eq user expect(book.reservation.due_date.present?).to be_falsey end end context 'when user has normal role' do let(:user) { User.new(role: [:normal]) } it "reserve and decrease remaining count and has no due date" do expect { reserve_book }.to change { user.remaining_count }.by(1) expect(book.reserved_user).to eq user expect(book.reservation.due_date.present?).to be_truthy end end end end Better /PUGood #FUUFS ʹॻ͍ͨ΄͏͕ඞཁͳ݅ظ͕͔Γ͍͢ RSpec.describe Book do describe '#reserve' do subject(:reserve_book) { book.reserve } let(:book) { Book.new } context 'when user has admin role' do let(:user) { User.new(role: [:admin]) } it "reserve and decrease remaining count and has no due date" do expect { reserve_book }.not_to change { user.remaining_count } expect(book.reserved_user).to eq user expect(book.reservation.due_date.present?).to be_falsey end end context 'when user has normal role' do let(:user) { User.new(role: [:normal]) } it "reserve and decrease remaining count and has no due date" do expect { reserve_book }.to change { user.remaining_count }.by(1) expect(book.reserved_user).to eq user expect(book.reservation.due_date.present?).to be_truthy end end end end
let!(:user) { User.new(remaining_count: 3) } it 'decrease remaining count by 1' do reserve_book expect(user.remaining_count).to eq 2 end end end Expect change Rspec.describe Book do describe '#reserve' do subject(:reserve_book) { book.reserve(user) } let!(:user) { User.new(remaining_count: 3) } it 'decrease remaining count by 1' do expect { reserve_book }.to change { user.remaining_count }.by(-1) end end end Better /PUGood
{ book.reserve } let(:book) { Book.new(available: true) } context 'when the book is not available' do before do book.update(available: false) end # ... end end end # Case 2 RSpec.describe Book do describe '#reserve' do subject { book.reserve } let(:book) { Book.new(available: available, country: country) } let(:available) { true } let(:country) { :jp } context 'when the book is not available' do let(:available) { false } # ... end end end Should not update context value RSpec.describe Book do describe '#reserve' do subject { book.reserve } let(:book) { Book.new(available: available, country: :jp) } context 'when the book is not available' do let(:available) { false } # ... end end end Better /PUGood
{ book.reserve } let(:book) { Book.new(available: true) } context 'when the book is not available' do before do book.update(available: false) end # ... end end end # Case 2 RSpec.describe Book do describe '#reserve' do subject { book.reserve } let(:book) { Book.new(available: available, country: country) } let(:available) { true } let(:country) { :jp } context 'when the book is not available' do let(:available) { false } # ... end end end Should not update context value RSpec.describe Book do describe '#reserve' do subject { book.reserve } let(:book) { Book.new(available: available, country: :jp) } context 'when the book is not available' do let(:available) { false } # ... end end end Better /PUGood /PUGood ͦͷ$POUFYUͰͷ࠷ऴతͳΛཧղͮ͠Β͘ͳΔ # Case 1 RSpec.describe Book do describe '#reserve' do subject { book.reserve } let(:book) { Book.new(available: true) } context 'when the book is not available' do before do book.update(available: false) end # ... end end end
{ book.reserve } let(:book) { Book.new(available: true) } context 'when the book is not available' do before do book.update(available: false) end # ... end end end # Case 2 RSpec.describe Book do describe '#reserve' do subject { book.reserve } let(:book) { Book.new(available: available, country: country) } let(:available) { true } let(:country) { :jp } context 'when the book is not available' do let(:available) { false } # ... end end end Should not update context value RSpec.describe Book do describe '#reserve' do subject { book.reserve } let(:book) { Book.new(available: available, country: :jp) } context 'when the book is not available' do let(:available) { false } # ... end end end Better /PUGood /PUGood MFUͰ্ॻ͖͢Δ߹ಉ͕͡ى͖Δ # Case 2 RSpec.describe Book do describe '#reserve' do subject { book.reserve } let(:book) { Book.new(available: available, country: country) } let(:available) { true } let(:country) { :jp } context 'when the book is not available' do let(:available) { false } # ... end end end
{ book.reserve } let(:book) { Book.new(available: true) } context 'when the book is not available' do before do book.update(available: false) end # ... end end end # Case 2 RSpec.describe Book do describe '#reserve' do subject { book.reserve } let(:book) { Book.new(available: available, country: country) } let(:available) { true } let(:country) { :jp } context 'when the book is not available' do let(:available) { false } # ... end end end Should not update context value RSpec.describe Book do describe '#reserve' do subject { book.reserve } let(:book) { Book.new(available: available, country: :jp) } context 'when the book is not available' do let(:available) { false } # ... end end end Better /PUGood #FUUFS DPOUFYUͰࢦఆ͢ΔσϑΥϧτΛઃఆ͠ͳ͍ RSpec.describe Book do describe '#reserve' do subject { book.reserve } let(:book) { Book.new(available: available, country: :jp) } context 'when the book is not available' do let(:available) { false } # ... end end end
do describe '#reserve' do subject { book.reserve } let(:book) { Book.new(available: available) } context 'when book.available == false' do let(:available) { false } # ... end end end RSpec.describe Book do describe '#reserve' do subject { book.reserve } let(:book) { Book.new(available: available) } context 'when the book can be reserved' do let(:available) { false } # ... end end end
Use let and before * Use subject and named subject * Reserved DRY * Expect change * Should not update context value * Write expectations at a high level * Should not use "should" in our example names