London from the Shard CC-BY DncnH
London from the Shard CC-BY DncnH
Juke
@Singsalad
Software Crafter
London from the Shard CC-BY DncnH
Test Driven Development
Repeat
London from the Shard CC-BY DncnH
Classic approach
(aka Detroit School)
London from the Shard CC-BY DncnH
Example
public class RomanNumeralsShould {
@Test public void convert_1_decimal_to_roman_numeral() {
RomanNumeral romanNumeral = new RomanNumeral(1);
assertThat(romanNumeral.toString(), is("I"));
}
@Test public void convert_2_decimal_to_roman_numeral() {
RomanNumeral romanNumeral = new RomanNumeral(2);
assertThat(romanNumeral.toString(), is("II"));
}
@Test public void convert_3_decimal_to_roman_numeral() {
RomanNumeral romanNumeral = new RomanNumeral(3);
assertThat(romanNumeral.toString(), is("III"));
}
}
London from the Shard CC-BY DncnH
Benefits
London from the Shard CC-BY DncnH
Drawbacks
London from the Shard CC-BY DncnH
When to use
London from the Shard CC-BY DncnH
From system entry point to single pieces of behaviour
Outside-In approach
(aka London School)
London from the Shard CC-BY DncnH
Next steps
London from the Shard CC-BY DncnH
Example
Feature request:
"As a party host, I want to send a notification to all my friends about my upcoming event so that they save the date."
London from the Shard CC-BY DncnH
Talk to the business
Save the date feature:
London from the Shard CC-BY DncnH
Start with an acceptance test
Given Ana is friends with Ben and Lara
And she has a birthday party on the 1st of March scheduled in the calendar
When she clicks on "Save the date"
Then A notification is sent to Ben and Lara with the date
London from the Shard CC-BY DncnH
Unit test EventPlan
public class EventPlanShould {
@Test public void
notify_friends_to_save_the_date() {
given(friendProvider.getFriendsOf(ANA))
.thenReturn(BEN, LARA);
given(calendar.getTimeOf(BIRTHDAY_PARTY))
.thenReturn(FIRST_OF_MARCH);
eventPlan.saveTheDate(ANA, BIRTHDAY_PARTY);
verify(notificationSender)
.notify(BEN, BIRTHDAY_PARTY, FIRST_OF_MARCH);
verify(notificationSender)
.notify(LARA, BIRTHDAY_PARTY, FIRST_OF_MARCH);
}}
London from the Shard CC-BY DncnH
Implement EventPlan
public class EventPlan { ...
public void saveTheDate(User host, Event event) {
Time timeOfEvent = calendar.getTimeOf(event);
List<Friend> friends =
friendProvider.getFriendsOf(host);
friends.stream()
.forEach(friend ->
notificationSender
.notify(friend,event,timeOfEvent));
}}
London from the Shard CC-BY DncnH
TDD Calendar
public class CalendarShould {
@Test public void provide_the_time_of_an_event() {
calendar
.addEvent(BIRTHDAY_PARTY, FIRST_OF_MARCH);
Time timeOfEvent =
calendar.getTimeOf(BIRTHDAY_PARTY);
assertThat(timeOfEvent, is(FIRST_OF_MARCH));
}
}
London from the Shard CC-BY DncnH
TDD FriendProvider
public class FriendProviderShould {
@Test public void provide_no_friends_of_a_user_without_friends() {
List<Friend> friends = friendProvider.getFriendsOf(ANA);
assertThat(friends,is(empty()));
}
@Test public void provide_a_single_friend_of_a_user() {
friendProvider.befriend(ANA, BEN);
List<Friend> friends = friendProvider.getFriendsOf(ANA);
assertThat(friends,contains(BEN);
}
@Test public void provide_all_friends_of_a_user() {
friendProvider.befriend(ANA, BEN);
friendProvider.befriend(ANA, LARA);
List<Friend> friends = friendProvider.getFriendsOf(ANA);
assertThat(friends,contains(BEN,LARA);
}}
London from the Shard CC-BY DncnH
And then...
London from the Shard CC-BY DncnH
Key differences
London from the Shard CC-BY DncnH
Benefits
London from the Shard CC-BY DncnH
Drawbacks
London from the Shard CC-BY DncnH
When & how to use
London from the Shard CC-BY DncnH
Which approach is better?
London from the Shard CC-BY DncnH
Further reading
London from the Shard CC-BY DncnH
Bank kata exercise
Create a simple bank application with the following features:
The statement should have the following format:
DATE | AMOUNT | BALANCE
10/04/2014 | 500.00 | 1400.00
02/04/2014 | -100.00 | 900.00
01/04/2014 | 1000.00 | 1000.00
London from the Shard CC-BY DncnH
Bank kata (2)
The entry point should be the following interface, which you can not change.
public class BankAccount {
public void deposit(int amount);
public void withdraw(int amount);
public void printStatement();
}
Don't worry about introducing abstractions on Money or Date as this is not the point of the exercise.
Start with an acceptance test!