Commit 9f9d0f4d by Patryk Czarnik

Przykład Konto z testami

parent 9ab0d0eb
package p20_konto;
public class BrakSrodkow extends Exception {
public BrakSrodkow() {
super();
}
public BrakSrodkow(String message) {
super(message);
}
}
package p20_konto;
public class EkperymentyZKontem {
public static void main(String[] args) {
Osoba jan = new Osoba("Jan", "Kowalski", 40);
Konto konto = new Konto(1313, 1000, jan);
System.out.println(konto);
konto.wplata(100);
System.out.println(konto);
konto.wplata(-300);
System.out.println(konto);
konto.wplata(-5000);
System.out.println(konto);
}
}
package p20_konto;
public class Konto {
private final int numer;
private int saldo;
private Osoba wlasciciel;
public Konto(int numer, int saldo, Osoba wlasciciel) {
this.numer = numer;
this.saldo = saldo;
this.wlasciciel = wlasciciel;
}
@Override
public String toString() {
return "Konto nr " + numer + ", saldo " + saldo + ", wł. " + wlasciciel;
}
public Osoba getWlasciciel() {
return wlasciciel;
}
public void setWlasciciel(Osoba wlasciciel) {
this.wlasciciel = wlasciciel;
}
public int getNumer() {
return numer;
}
public int getSaldo() {
return saldo;
}
// Dla pola numer nie tworzę settera, gdyż numer konta się nie zmienia.
// Dodatkowo jest to zapewnione modyfikatorem final.
// Dla pola saldo nie tworzę settera, gdyż salda nie ustawia się "bez żadnego trybu",
// tylko saldo można zmodyfikować poprzez operacje biznesowe: wplata, wyplata, przelew.
public void wplata(int kwota) {
if(kwota <= 0) {
throw new IllegalArgumentException("Kwota nie jest dodatnia");
}
saldo += kwota;
}
public void wyplata(int kwota) throws BrakSrodkow {
if(kwota <= 0) {
throw new IllegalArgumentException("Kwota nie jest dodatnia");
}
if(kwota > saldo) {
throw new BrakSrodkow("Za mało kasy podczas wypłaty");
}
saldo -= kwota;
}
public void przelew(int kwota, Konto kontoDocelowe) throws BrakSrodkow {
if(kwota <= 0) {
throw new IllegalArgumentException("Kwota nie jest dodatnia");
}
if(kwota > saldo) {
throw new BrakSrodkow("Za mało kasy podczas przelewu");
}
this.saldo -= kwota;
kontoDocelowe.saldo += kwota;
}
}
package p20_konto;
import java.time. LocalDate;
import java.time.Period;
import java.time.temporal.ChronoUnit;
public class Osoba {
private String imie;
private String nazwisko;
private LocalDate dataUrodzenia;
public Osoba(String imie, String nazwisko, LocalDate dataUrodzenia) {
this.imie = imie;
this.nazwisko = nazwisko;
this.dataUrodzenia = dataUrodzenia;
}
public Osoba(String imie, String nazwisko, String dataUrodzenia) {
this(imie, nazwisko, LocalDate.parse(dataUrodzenia));
}
public Osoba(String imie, String nazwisko, int wiek) {
this(imie, nazwisko, LocalDate.now().minus(wiek, ChronoUnit.YEARS));
}
public String getImie() {
return imie;
}
public String getNazwisko() {
return nazwisko;
}
public LocalDate getDataUrodzenia() {
return dataUrodzenia;
}
public int getWiek() {
Period czasZycia = Period.between(dataUrodzenia, LocalDate.now()); // ile lat, miesięcy, dni
return czasZycia.getYears(); // ile pełnych lat
}
public void setImie(String imie) {
this.imie = imie;
}
public void setNazwisko(String nazwisko) {
this.nazwisko = nazwisko;
}
@Override
public String toString() {
return imie + " " + nazwisko + ", ur. " + dataUrodzenia;
}
}
package p20_konto;
import java.time.LocalDate;
public class Program {
public static void main(String[] args) {
Osoba ala = new Osoba("Ala", "Kowalska", LocalDate.of(2003, 6, 23));
System.out.println(ala);
System.out.println(ala.getImie() + " ma " + ala.getWiek() + " lat");
ala.setImie("Alicja");
System.out.println(ala.getImie() + " ma " + ala.getWiek() + " lat");
Osoba ola = new Osoba("Ola", "Malinowska", 30);
System.out.println(ola);
Osoba adam = new Osoba("Adam", "Abacki", "1975-11-24");
System.out.println(adam);
System.out.println(adam.getWiek());
System.out.println();
Konto kontoAli = new Konto(1, 1000, ala);
Konto kontoOli = new Konto(2, 2000, ola);
System.out.println(kontoAli);
System.out.println(kontoOli);
System.out.println();
kontoAli.wplata(500);
try {
kontoOli.wyplata(100);
} catch (BrakSrodkow e) {
System.err.println(e);
}
System.out.println(kontoAli);
System.out.println(kontoOli);
System.out.println();
try {
kontoAli.przelew(333, kontoOli);
} catch (BrakSrodkow e) {
System.err.println(e);
}
System.out.println(kontoAli);
System.out.println(kontoOli);
}
}
package p20_konto;
import java.util.Scanner;
public class ProgramBankowy {
public static void main(String[] args) {
@SuppressWarnings("resource")
Scanner sc = new Scanner(System.in);
Osoba ala = new Osoba("Ala", "Kowalska", "1985-05-05");
System.out.print("Podaj początkową kwotę: ");
int kwota = sc.nextInt();
sc.nextLine(); // wymuszenie przejścia do nowej linii
Konto konto = new Konto(1, kwota, ala);
System.out.println(konto);
petla:
while(true) {
try {
System.out.println("Co chcesz zrobić? W - wpłata, Y - wypłata, K - koniec");
String wybor = sc.nextLine().toUpperCase();
switch(wybor) {
case "K", "Q":
break petla; // przejście do Koniec programu
case "W":
System.out.print("Podaj kwotę wpłaty: ");
kwota = sc.nextInt();
sc.nextLine();
konto.wplata(kwota);
System.out.println("Pieniądze zostały wpłacone");
break;
case "Y":
System.out.print("Podaj kwotę wypłaty: ");
kwota = sc.nextInt();
sc.nextLine();
konto.wyplata(kwota);
// ta linia wykona się tylko jeśli nie było wyjątku:
System.out.println("Pieniądze zostały wypłacone");
break;
default:
System.out.println("Nieznane polecenie");
continue petla; // Przejście do Co chcesz zrobić
}
// Jeśli o różnych sytuacjach błędnych będą informować wyjątki różnych klas,
// to w programie możemy te sytuacje rozróżnić i obsłużyć w róznych catchach
} catch(IllegalArgumentException e) {
System.out.println("Niepoprawny argument: " + e);
} catch(BrakSrodkow e) {
System.out.println(e.getMessage());
} catch(Exception e) {
System.out.println("Inny błąd: " + e);
}
System.out.println();
System.out.println(konto);
System.out.println();
}
System.out.println("Koniec programu");
}
}
package p20_konto;
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.Test;
class KontoTest {
@Test
void testToString() {
System.out.println("początek testu toString");
Osoba ala = new Osoba("Ala", "Kowalska", "2000-01-01");
Konto konto = new Konto(1, 1000, ala);
assertEquals("Konto nr 1, saldo 1000, wł. Ala Kowalska, ur. 2000-01-01", konto.toString());
System.out.println("koniec testu toString");
}
@Test
void testWplata() {
Osoba ala = new Osoba("Ala", "Kowalska", "2000-01-01");
Konto konto = new Konto(1, 1000, ala);
konto.wplata(200);
assertEquals(1200, konto.getSaldo());
}
@Test
void testWyplata() throws BrakSrodkow {
Osoba ala = new Osoba("Ala", "Kowalska", "2000-01-01");
Konto konto = new Konto(1, 1000, ala);
konto.wyplata(300);
assertEquals(700, konto.getSaldo());
}
@Test
void testPrzelew() throws BrakSrodkow {
Osoba ala = new Osoba("Ala", "Kowalska", "2000-01-01");
Konto konto1 = new Konto(1, 1000, ala);
Konto konto2 = new Konto(2, 2000, ala);
konto1.przelew(400, konto2);
assertEquals(600, konto1.getSaldo());
assertEquals(2400, konto2.getSaldo());
}
}
package p20_konto;
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
class KontoTestyZaawansowane {
private Konto konto;
@BeforeEach
void setUp() {
// Metoda oznaczona @BeforeEach wykona się przed każdym testem
Osoba ala = new Osoba("Ala", "Kowalska", "2000-01-01");
konto = new Konto(1, 1000, ala);
}
// Analogicznie @AfterEach (tradycyjna nazwa tearDown) - wykonywana po każdym teście.
@Test
void testToString() {
assertEquals("Konto nr 1, saldo 1000, wł. Ala Kowalska, ur. 2000-01-01", konto.toString());
}
@Test
void testWplata() {
konto.wplata(200);
assertEquals(1200, konto.getSaldo());
}
@Test
void testWyplata() throws BrakSrodkow {
konto.wyplata(300);
assertEquals(700, konto.getSaldo());
}
@Test
void testPrzelew() throws BrakSrodkow {
Konto konto2 = new Konto(2, 2000, null);
konto.przelew(400, konto2);
assertEquals(600, konto.getSaldo());
assertEquals(2400, konto2.getSaldo());
}
@Test
void testWplataUjemna() {
assertThrows(IllegalArgumentException.class, () -> {
konto.wplata(-200);
});
assertEquals(1000, konto.getSaldo());
}
// ↑To pisaliśmy na zajęciach ↑
// ↓To wklejam gotowe ↓
// Temat sprawdzania wyjątków w testach.
// Aby stwierdzić, że w pewnej sytuacji metoda POWINNA skończyć się wyjątkiem,
// możemy użyć odpowiednio try-catch (testWplataTry)
// albo użyć dedykowanych rozwiązań JUnit - dalsze przykłady
@Test
void testWplataTry() {
try {
konto.wplata(-100);
// Gdyby nie było wyjątku i program doszedłby do tego miejsca,
// test powinien skończyć się porażką
fail("Powinien być wyjątek, a nie ma.");
} catch(IllegalArgumentException e) {
// Jeśli wyłapiemy wyjątek, możemy sprawdzić w teście jego szczegóły,
// np. jaki jest message (bardzo rzadko takie rzeczy sprawdza się w testach, ale można):
assertEquals("Niedodatnia kwota w metodzie wplata", e.getMessage());
} finally {
// Możemy też upewnić się, że w przypadku wystąpienia wyjątku stan konta się nie zmienił.
assertEquals(1000, konto.getSaldo());
}
}
// Analogiczny test można też napisać wykorzystując nową funkcjonalność JUnit 5:
@Test
void testWplataUjemna_v1() {
// assertThrows wykonuje podany fragment kodu (w praktyce podaje się wyrażenie lambda)
// i sprawdza czy ten kończy się podanym rodzajem wyjątku.
// Jeśli jest wyjątek - dobrze
// Jeśli nie ma wyjątku - test failuje
assertThrows(IllegalArgumentException.class, () -> {
konto.wplata(-100);
});
// Dodatkowo po wykonaniu assertThrows możemy sprawdzić jaki jest stan końcowy,
// np. czy saldo się nie zmieniło.
assertEquals(1000, konto.getSaldo());
}
// Aby sprawdzić jaki jest message w wyjątku itp, możemy odebrać obiekt wyjątku i sprawdzić bezpośrednio
@Test
void testWplataUjemna_v2() {
IllegalArgumentException exception = assertThrows(IllegalArgumentException.class, () -> {
konto.wplata(-100);
});
assertEquals("Niedodatnia kwota w metodzie wplata", exception.getMessage());
assertEquals(1000, konto.getSaldo());
}
@Test
void testWyplataUjemna() {
assertThrows(IllegalArgumentException.class, () -> {
konto.wyplata(-100);
});
assertEquals(1000, konto.getSaldo());
}
@Test
void testBrakSrodkow() {
assertThrows(BrakSrodkow.class, () -> {
konto.wyplata(1300);
});
assertEquals(1000, konto.getSaldo());
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment