Skriva bankkärnpaketet
Nu när basprojektet körs tillsammans med vår testfil ska vi börja skriva koden som implementerar den tidigare enhetens funktioner och krav. Här går vi tillbaka till några ämnen som vi diskuterade tidigare, till exempel fel, strukturer och metoder.
$GOPATH/src/bankcore/bank.go
Öppna filen, ta bort Hello()
funktionen och börja skriva kärnlogik i vårt onlinebanksystem.
Skapa strukturer för kunder och konton
Vi börjar med att skapa en Customer
struktur där vi har namn, adress och telefonnummer från en person som vill bli bankkund. Dessutom behöver vi en struktur för Account
data. Eftersom en kund kan ha fler än ett konto ska vi bädda in kundinformationen i kontoobjektet. I grund och botten ska vi skapa det vi definierade i TestAccount
testet.
De strukturer som vi behöver kan se ut som i följande kodexempel:
package bank
// Customer ...
type Customer struct {
Name string
Address string
Phone string
}
// Account ...
type Account struct {
Customer
Number int32
Balance float64
}
När du kör kommandot i terminalen go test -v
nu bör du se att testet skickas:
=== RUN TestAccount
--- PASS: TestAccount (0.00s)
PASS
ok github.com/msft/bank 0.094s
Det här testet skickas eftersom vi implementerade strukturerna för Customer
och Account
. Nu när vi har strukturerna ska vi skriva metoderna för att lägga till de funktioner som vi behöver i den första versionen av vår bank. Dessa funktioner inkluderar insättning, uttag och överföring av pengar.
Implementera insättningsmetoden
Vi måste börja med en metod som gör det möjligt att lägga till pengar på vårt konto. Men innan vi gör det ska vi skapa TestDeposit
funktionen i bank_test.go
filen:
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")
}
}
När du kör go test -v
bör du se ett misslyckat test i utdata:
# 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]
För att uppfylla föregående test ska vi skapa en Deposit
metod för vår Account
struktur som returnerar ett fel om det mottagna beloppet är lika med eller lägre än noll. Annars lägger du bara till det mottagna beloppet i saldot för kontot.
Använd följande kod för Deposit
metoden:
// 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
}
När du kör go test -v
bör du se att testet skickas:
=== RUN TestAccount
--- PASS: TestAccount (0.00s)
=== RUN TestDeposit
--- PASS: TestDeposit (0.00s)
PASS
ok github.com/msft/bank 0.193s
Du kan också skriva ett test som bekräftar att du får ett fel när du försöker sätta in ett negativt belopp, så här:
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")
}
}
När du kör go test -v
kommandot bör du se att testet skickas:
=== 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
Kommentar
Härifrån skriver vi ett testfall för varje metod. Men du bör skriva så många tester till dina program som du känner dig bekväm med, så att du kan täcka både förväntade och oväntade scenarier. I det här fallet testas till exempel felhanteringslogik.
Implementera återdragningsmetoden
Innan vi skriver Withdraw
funktionen ska vi skriva testet för det:
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")
}
}
När du kör go test -v
kommandot bör du se ett misslyckat test i utdata:
# 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]
Nu ska vi implementera logiken Withdraw
för metoden, där vi minskar saldot för kontot med det belopp som vi får som parameter. Precis som vi gjorde tidigare måste vi verifiera att det antal vi får är större än noll och att saldot i kontot räcker.
Använd följande kod för Withdraw
metoden:
// 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
}
När du kör go test -v
kommandot bör du se att testet skickas:
=== 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
Implementera instruktionsmetoden
Nu ska vi skriva en metod för att skriva ut -instruktionen som innehåller kontonamnet, numret och saldot. Men först ska vi skapa TestStatement
funktionen:
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")
}
}
När du kör go test -v
bör du se ett misslyckat test i utdata:
# 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]
Nu ska vi skriva Statement
metoden, som ska returnera en sträng. (Du måste skriva över den här metoden senare som en utmaning.) Använd följande kod:
// Statement ...
func (a *Account) Statement() string {
return fmt.Sprintf("%v - %v - %v", a.Number, a.Name, a.Balance)
}
När du kör go test -v
bör du se att testet skickas:
=== 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
Nu går vi vidare till nästa avsnitt och skriver webb-API:et Statement
som exponerar metoden.