Skip to content

Birthdays exercise for doubles and stubbing#24

Open
lildann wants to merge 7 commits intomakersacademy:masterfrom
lildann:main
Open

Birthdays exercise for doubles and stubbing#24
lildann wants to merge 7 commits intomakersacademy:masterfrom
lildann:main

Conversation

@lildann
Copy link
Copy Markdown

@lildann lildann commented Nov 16, 2021

Please could I request a review for this exercise? Particularly how I tested with doubles and stubbing, and how I could expand on this, and also how my classes interact. I had trouble mocking the Time.now object - is there a better way to do this? Thanks so much.

Copy link
Copy Markdown

@alicelieutier alicelieutier left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nicely done. Overall your tests and doubles are good. You can decouple classes more, and have more tests focused on logic. See comments below.

Comment thread lib/birthday_list.rb
end

def see_birthdays
@birthdays.each { |birthday| puts "#{birthday.name}: #{birthday.date}"}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could decouple your classes more here by delegating to birthday how to show a birthday, so this becomes:

@birthdays.each { |birthday| puts birthday.display }

or something equivalent.

Comment thread lib/birthday_list.rb
def check_birthday
@birthdays.each do |birthday|
if today == birthday.date[0..4]
puts "It's #{birthday.name}'s birthday today! They are #{birthday.calculate_age} years old!"
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here, the birthday class could be responsible for checking the date against today and creating this string.

Comment thread lib/birthday_list.rb
Comment on lines +26 to +28
def today
Time.now.strftime("%d/%m")
end
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This way you would not need today in this class.

Comment on lines +8 to +11
it 'stores a birthday in a list' do
birthday_list.store_birthday(my_birthday)
expect(birthday_list.birthdays).to include(my_birthday)
end
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Storing is not really behaviour (it doesn't leave the class, like an output or a call to method of another class). I would remove this test, to focus on testing behaviour only.

allow(your_birthday).to receive_messages(name: 'Fred', date: '23/05/1989')
birthday_list.store_birthday(my_birthday)
birthday_list.store_birthday(your_birthday)
expect { birthday_list.see_birthdays }.to output("Lilly: 01/03/1989\nFred: 23/05/1989\n").to_stdout
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a great test of behaviour!

end

it 'checks if a birthday is today and returns a message if so (timecop)' do
fake_today = Timecop.freeze(Time.local(2021, 03, 01))
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is good! no need to store into a variable, just this is enough:

Timecop.freeze(Time.local(2021, 03, 01))

fake_today = Timecop.freeze(Time.local(2021, 03, 01))
allow(my_birthday).to receive_messages(name: 'Lilly', date: '01/03/1989', calculate_age: '32')
birthday_list.store_birthday(my_birthday)
expect { birthday_list.check_birthday }.to output("It's #{my_birthday.name}'s birthday today! They are #{my_birthday.calculate_age} years old!\n").to_stdout
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comment as previous test.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you change the string to a fixed one, then you'll have removed all the logic from your test and it will be perfect ;)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

However, you may want to add more tests. Maybe a second one with a different name and age, just to make sure that they get picked (otherwise, this test could pass even if your method always returned Lilly's name for example).

Comment on lines +35 to +39
it '#check_birthday returns nothing if birthday not today' do
fake_today = Timecop.freeze(Time.local(2021, 11, 17))
allow(my_birthday).to receive_messages(name: 'Lilly', date: '01/03/1989', calculate_age: '32')
birthday_list.store_birthday(my_birthday)
expect { birthday_list.check_birthday }.not_to output.to_stdout
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good!

Comment thread spec/birthday_spec.rb
Comment on lines +4 to +7
it 'should be initialized with a name and a birthday' do
my_birthday = Birthday.new('Lilly', '01/03/1989')
expect(my_birthday.name).to eq('Lilly')
expect(my_birthday.date).to eq('01/03/1989')
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is storage not behaviour, you can remove these tests.

Comment thread spec/birthday_spec.rb
Comment on lines +10 to +15
it "should calculate the person's age" do
my_birthday = Birthday.new('Lilly', '01/03/1989')
their_birthday = Birthday.new('Fred', '18/12/1989')
expect(my_birthday.calculate_age).to eq(32)
expect(their_birthday.calculate_age).to eq(31)
end
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make this two different tests. Maybe also ad a third with a different age. This is good :) Most of the logic in your class is around calculating age, it makes sense that it gets more tests.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants