Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Birthdays exercise for doubles and stubbing #24

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open

Birthdays exercise for doubles and stubbing #24

wants to merge 7 commits into from

Conversation

lildann
Copy link

@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

@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.

end

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

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.

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!"

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 on lines +26 to +28
def today
Time.now.strftime("%d/%m")
end

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

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

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))

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

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.

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 ;)

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

Choose a reason for hiding this comment

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

Good!

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')

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

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