Schreiben des Kernpakets für die Bank

Abgeschlossen

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.