Écrire le package principal de la banque
Maintenant que nous avons le projet de base en cours d’exécution avec notre fichier de test, commençons par écrire le code qui implémente les fonctionnalités et les exigences de l’unité précédente. Ici, nous revisitons quelques sujets abordés plus tôt, tels que les erreurs, structures et méthodes.
Ouvrez le fichier $GOPATH/src/bankcore/bank.go
, supprimez la fonction Hello()
, puis commencez à écrire la logique principale de notre système bancaire.
Créer des structures pour les clients et les comptes
Commençons par créer une structure Customer
dans laquelle nous avons le nom, l’adresse et le numéro de téléphone d’une personne qui souhaite devenir client de la banque. Nous avons également besoin d’une structure pour les données de Account
. Étant donné qu’un client peut avoir plusieurs comptes, nous allons incorporer les informations client dans l’objet du compte. Fondamentalement, nous allons créer ce que nous avons défini dans le test TestAccount
.
Les structures dont nous avons besoin peuvent ressembler à l’exemple de code suivant :
package bank
// Customer ...
type Customer struct {
Name string
Address string
Phone string
}
// Account ...
type Account struct {
Customer
Number int32
Balance float64
}
Quand vous exécutez la commande go test -v
dans votre terminal, vous devez voir que le test réussit :
=== RUN TestAccount
--- PASS: TestAccount (0.00s)
PASS
ok github.com/msft/bank 0.094s
Ce test réussit, car nous avons implémenté les structures pour Customer
et Account
. Maintenant que nous disposons des structures, nous allons écrire les méthodes permettant d’ajouter les fonctionnalités dont nous avons besoin dans la version initiale de notre banque. Ces fonctionnalités incluent le dépôt, le retrait et le transfert d’argent.
Implémenter la méthode de dépôt
Nous devons commencer par une méthode qui permet d’ajouter de l’argent à notre compte. Mais avant cela, nous allons créer la fonction TestDeposit
dans le fichier bank_test.go
:
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")
}
}
Lorsque vous exécutez go test -v
, vous devez voir un test d’échec dans le résultat :
# 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]
Pour satisfaire le test précédent, nous allons créer une méthode Deposit
pour notre structure Account
qui retourne une erreur si le montant reçu est inférieur ou égal à zéro. Dans le cas contraire, ajoutez le montant reçu au solde du compte.
Utilisez le code suivant pour la méthode Deposit
:
// 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
}
Lorsque vous exécutez go test -v
, vous devez voir que le test est réussi :
=== RUN TestAccount
--- PASS: TestAccount (0.00s)
=== RUN TestDeposit
--- PASS: TestDeposit (0.00s)
PASS
ok github.com/msft/bank 0.193s
Vous pouvez également écrire un test qui confirme que vous recevez une erreur lorsque vous essayez de déposer un montant négatif, comme suit :
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")
}
}
Lorsque vous exécutez go test -v
, vous devez voir que le test est réussi :
=== 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
Notes
À partir de là, nous allons écrire un cas de test pour chaque méthode. Mais vous devez écrire autant de tests que vous le souhaitez dans vos programmes. Vous pouvez ainsi couvrir les scénarios attendus et inattendus. Par exemple, dans ce cas, la logique de gestion des erreurs est testée.
Implémenter la méthode de retrait
Avant d’écrire la fonctionnalité Withdraw
, nous allons écrire le test pour celle-ci :
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")
}
}
Quand vous exécutez la commande go test -v
, vous devez voir un test ayant échoué dans la sortie :
# 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]
Nous allons implémenter la logique de la méthode Withdraw
, où nous diminuons le solde du compte en fonction de la valeur que nous recevons en tant que paramètre. Comme nous l’avons fait précédemment, nous devons confirmer que le nombre que nous recevons est supérieur à zéro et que le solde du compte est suffisant.
Utilisez le code suivant pour la méthode Withdraw
:
// 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
}
Lorsque vous exécutez go test -v
, vous devez voir que le test est réussi :
=== 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
Implémenter la méthode d’instruction
Nous allons écrire une méthode pour imprimer l’instruction qui comprend le nom, le numéro et le solde du compte. Commençons donc par créer la fonction TestStatement
:
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")
}
}
Lorsque vous exécutez go test -v
, vous devez voir un test d’échec dans le résultat :
# 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]
Nous allons écrire la méthode Statement
, qui doit retourner une chaîne. (Vous devrez remplacer cette méthode en tant que défi un peu plus tard.) Utilisez le code suivant :
// Statement ...
func (a *Account) Statement() string {
return fmt.Sprintf("%v - %v - %v", a.Number, a.Name, a.Balance)
}
Lorsque vous exécutez go test -v
, vous devez voir que le test est réussi :
=== 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
Passons à la section suivante pour écrire l’API web qui expose la méthode Statement
.