Schreiben des Kernpakets für die Bank
Nachdem das Basisprojekt jetzt zusammen mit unserer Testdatei ausgeführt wird, können wir damit beginnen, den Code zu schreiben, der die Features und Anforderungen der vorherigen Lerneinheit implementiert. Hier wiederholen wir einige Themen, die wir zuvor behandelt haben, wie Fehler, Strukturen und Methoden.
Öffnen Sie die $GOPATH/src/bankcore/bank.go
-Datei, entfernen Sie die Hello()
-Funktion, und beginnen Sie mit dem Schreiben der Kernlogik unseres Onlinebanksystems.
Erstellen von Strukturen für Kunden und Konten
Beginnen wir mit dem Erstellen einer Customer
-Struktur, in der wir den Namen, die Adresse und die Telefonnummer einer Person speichern, die Kunde der Bank werden möchte. Außerdem benötigen wir eine Struktur für die Account
-Daten. Da ein Kunde mehr als ein Konto besitzen kann, betten wir die Kundeninformationen in das Kontoobjekt ein. Im Grunde genommen erstellen wir das, was wir im TestAccount
-Test definiert haben.
Die erforderlichen Strukturen könnten wie das folgende Codebeispiel aussehen:
package bank
// Customer ...
type Customer struct {
Name string
Address string
Phone string
}
// Account ...
type Account struct {
Customer
Number int32
Balance float64
}
Wenn Sie den go test -v
-Befehl jetzt in Ihrem Terminal ausführen, sollten Sie sehen, dass der Test erfolgreich ist:
=== RUN TestAccount
--- PASS: TestAccount (0.00s)
PASS
ok github.com/msft/bank 0.094s
Dieser Test ist erfolgreich, da wir die Strukturen für Customer
und Account
implementiert haben. Nachdem wir jetzt über die Strukturen verfügen, lassen Sie uns die Methoden zum Hinzufügen der Features schreiben, die wir in der ersten Version unserer Bank benötigen. Zu diesen Features gehören das Einzahlen, Abheben und Überweisen von Geld.
Implementieren der Einzahlungsmethode
Wir müssen mit einer Methode beginnen, die es ermöglicht, Geld auf unser Konto einzuzahlen. Zuvor erstellen wir jedoch die TestDeposit
-Funktion in der bank_test.go
-Datei:
func TestDeposit(t *testing.T) {
account := Account{
Customer: Customer{
Name: "John",
Address: "Los Angeles, California",
Phone: "(213) 555 0147",
},
Number: 1001,
Balance: 0,
}
account.Deposit(10)
if account.Balance != 10 {
t.Error("balance is not being updated after a deposit")
}
}
Wenn Sie go test -v
ausführen, sollte ein fehlerhafter Test in der Ausgabe angezeigt werden:
# github.com/msft/bank [github.com/msft/bank.test]
./bank_test.go:32:9: account.Deposit undefined (type Account has no field or method Deposit)
FAIL github.com/msft/bank [build failed]
Um dem vorherigen Test gerecht zu werden, erstellen wir eine Deposit
-Methode für unsere Account
Struktur, die einen Fehler zurückgibt, wenn der empfangene Betrag gleich oder kleiner als Null ist. Andernfalls addieren Sie einfach den erhaltenen Betrag zum Saldo des Kontos.
Verwenden Sie den folgenden Code für die Deposit
-Methode:
// Deposit ...
func (a *Account) Deposit(amount float64) error {
if amount <= 0 {
return errors.New("the amount to deposit should be greater than zero")
}
a.Balance += amount
return nil
}
Wenn Sie go test -v
ausführen, sollten Sie sehen, dass der Test erfolgreich durchgeführt wurde:
=== RUN TestAccount
--- PASS: TestAccount (0.00s)
=== RUN TestDeposit
--- PASS: TestDeposit (0.00s)
PASS
ok github.com/msft/bank 0.193s
Sie können auch einen Test schreiben, der bestätigt, dass Sie einen Fehler erhalten, wenn Sie versuchen, einen negativen Betrag einzuzahlen. Beispiel:
func TestDepositInvalid(t *testing.T) {
account := Account{
Customer: Customer{
Name: "John",
Address: "Los Angeles, California",
Phone: "(213) 555 0147",
},
Number: 1001,
Balance: 0,
}
if err := account.Deposit(-10); err == nil {
t.Error("only positive numbers should be allowed to deposit")
}
}
Wenn Sie den go test -v
-Befehl ausführen, sollten Sie sehen, dass der Test erfolgreich durchgeführt wurde:
=== RUN TestAccount
--- PASS: TestAccount (0.00s)
=== RUN TestDeposit
--- PASS: TestDeposit (0.00s)
=== RUN TestDepositInvalid
--- PASS: TestDepositInvalid (0.00s)
PASS
ok github.com/msft/bank 0.197s
Hinweis
Von hier an schreiben wir für jede Methode einen Testfall. Aber Sie sollten eine Ihrer Meinung nach geeignete Anzahl von Tests zu Ihren Programmen schreiben, sodass Sie sowohl erwartete als auch unerwartete Szenarien abdecken können. In diesem Fall wird z. B. die Logik für die Fehlerbehandlung getestet.
Implementieren der Auszahlungsmethode
Bevor wir die Withdraw
-Funktion erstellen, schreiben wir den zugehörigen Test:
func TestWithdraw(t *testing.T) {
account := Account{
Customer: Customer{
Name: "John",
Address: "Los Angeles, California",
Phone: "(213) 555 0147",
},
Number: 1001,
Balance: 0,
}
account.Deposit(10)
account.Withdraw(10)
if account.Balance != 0 {
t.Error("balance is not being updated after withdraw")
}
}
Wenn Sie den go test -v
-Befehl ausführen, sollte ein fehlerhafter Test in der Ausgabe angezeigt werden:
# github.com/msft/bank [github.com/msft/bank.test]
./bank_test.go:67:9: account.Withdraw undefined (type Account has no field or method Withdraw)
FAIL github.com/msft/bank [build failed]
Lassen Sie uns die Logik für die Withdraw
-Methode implementieren, bei der wir den Saldo um den Betrag reduzieren, den wir als Parameter erhalten. Wie zuvor müssen wir überprüfen, ob die empfangene Zahl größer als Null und das Guthaben auf dem Konto ausreichend ist.
Verwenden Sie den folgenden Code für die Withdraw
-Methode:
// Withdraw ...
func (a *Account) Withdraw(amount float64) error {
if amount <= 0 {
return errors.New("the amount to withdraw should be greater than zero")
}
if a.Balance < amount {
return errors.New("the amount to withdraw should be less than the account's balance")
}
a.Balance -= amount
return nil
}
Wenn Sie den go test -v
-Befehl ausführen, sollten Sie sehen, dass der Test erfolgreich durchgeführt wurde:
=== RUN TestAccount
--- PASS: TestAccount (0.00s)
=== RUN TestDeposit
--- PASS: TestDeposit (0.00s)
=== RUN TestDepositInvalid
--- PASS: TestDepositInvalid (0.00s)
=== RUN TestWithdraw
--- PASS: TestWithdraw (0.00s)
PASS
ok github.com/msft/bank 0.250s
Implementieren der Auszugsmethode
Lassen Sie uns eine Methode schreiben, um einen Auszug zu drucken, der Kontoname, Kontonummer und Saldo enthält. Lassen Sie uns aber zunächst die TestStatement
-Funktion erstellen:
func TestStatement(t *testing.T) {
account := Account{
Customer: Customer{
Name: "John",
Address: "Los Angeles, California",
Phone: "(213) 555 0147",
},
Number: 1001,
Balance: 0,
}
account.Deposit(100)
statement := account.Statement()
if statement != "1001 - John - 100" {
t.Error("statement doesn't have the proper format")
}
}
Wenn Sie go test -v
ausführen, sollte ein fehlerhafter Test in der Ausgabe angezeigt werden:
# github.com/msft/bank [github.com/msft/bank.test]
./bank_test.go:86:22: account.Statement undefined (type Account has no field or method Statement)
FAIL github.com/msft/bank [build failed]
Schreiben Sie die Statement
-Methode, die eine Zeichenfolge zurückgeben soll. (Sie müssen diese Methode später als Herausforderung überschreiben.) Verwenden Sie den folgenden Code:
// Statement ...
func (a *Account) Statement() string {
return fmt.Sprintf("%v - %v - %v", a.Number, a.Name, a.Balance)
}
Wenn Sie go test -v
ausführen, sollten Sie sehen, dass der Test erfolgreich durchgeführt wurde:
=== RUN TestAccount
--- PASS: TestAccount (0.00s)
=== RUN TestDeposit
--- PASS: TestDeposit (0.00s)
=== RUN TestDepositInvalid
--- PASS: TestDepositInvalid (0.00s)
=== RUN TestWithdraw
--- PASS: TestWithdraw (0.00s)
=== RUN TestStatement
--- PASS: TestStatement (0.00s)
PASS
ok github.com/msft/bank 0.328s
Gehen wir zum nächsten Abschnitt über, und schreiben Sie die Web-API, um die die Statement
-Methode verfügbar macht.