Przykład. Załóżmy, że chcesz liczyć pseudo-średnią arytmetyczną grupy (nie wiesz jeszcze grupy czego), ale niech to będzie grupa czegoś, co zwraca swoje osiągnięcie/rezultat.
/Nie mockuje się czegoś co ma liczyć średnią (5+7)/2 ale chciałem na szybko jakiś nieskomplikowany przykład/
To coś można opisać interfejsem Scorable (internety podają: scorable, a nie scoreable)
@FunctionalInterface
public interface Scorable {
int getScore();
}
Jeszcze nie wiadomo co to konkretnie będzie. :)
Wiadomo, że na wynikach będzie się robić zestawienia, np. pseudoŚrednia wszystkich w ekipie "Scorables"
public class TeamScores {
private final List<Scorable> scores = new ArrayList<>();
public void add(Scorable scorable) {
if (scorable == null) {
throw new IllegalArgumentException();
}
scores.add(scorable);
}
public int naiveArithmeticMean() {
//
}
}
Żeby sprawdzić, czy dobrze się policzy, to
albo robimy implementację interfejsu Scorable i sprawdzamy
albo nie robimy implementacji i symulujemy zachowanie kiedyś w przyszłosci dodanej implementacji (na razie jej nie mamy), są tylko testy
coś większego, Mockito - rozwlekle
@Test
public void fiveAndSevenShouldGiveSix() {
final Scorable scorable5 = Mockito.mock(Scorable.class);
Mockito
.when(scorable5.getScore())
.thenReturn(5);
final Scorable scorable7 = Mockito.mock(Scorable.class);
Mockito
.when(scorable7.getScore())
.thenReturn(7);
teamScores.add(scorable5);
teamScores.add(scorable7);
final int mean = teamScores.naiveArithmeticMean();
assertThat(mean, is(6));
}
albo po prostu zamiast Mockito zwykły javowy Supplier - zwięźle
@Test
public void fiveTenFifteenShouldGiveTen() {
teamScores.add(() -> 5);
teamScores.add(() -> 10);
teamScores.add(() -> 15);
assertThat(teamScores.naiveArithmeticMean(), is(10));
}
Jest interfejs jako argument, więc można tymczasowo całą implementację i instancję zastąpić w testach przez krótkie
() -> 5
Co będzie póżniej implementować Scorable to nie ważne, liczy się, że teraz tylko metoda getScore(), którą zdefiniował interfejs Scorable