factory.go
package factory import ( "errors" "fmt" ) const ( Cash = 1 DebitCard = 2 ) type PaymentMethod interface { Pay(amount float32) string } type CashPM struct{} type DebitCardPM struct{} func GetPaymentMethod(m int) (PaymentMethod, error) { switch m { case Cash: return new(CashPM), nil case DebitCard: return new(DebitCardPM), nil default: return nil, errors.New(fmt.Sprintf("Payment method %d not recognized\n", m)) } } func (c *CashPM) Pay(amount float32) string { return fmt.Sprintf("%0.2f paid using cash\n", amount) } func (c *DebitCardPM) Pay(amount float32) string { return fmt.Sprintf("%#0.2f paid using debit card\n", amount) }
factory_test.go
package factory import ( "strings" "testing" ) func TestCreatePaymentMethodCash(t *testing.T) { payment, err := GetPaymentMethod(Cash) if err != nil { t.Fatal("A payment method of type 'Cash' must exist.") } msg := payment.Pay(10.30) if !strings.Contains(msg, "paid using cash") { t.Error("The cash payment method message was't correct") } t.Log("LOG: ", msg) } func TestGetPaymentMethodDebitCard(t *testing.T) { payment, err := GetPaymentMethod(DebitCard) if err != nil { t.Fatal("A payment method of type 'DebitCard' must exist.") } msg := payment.Pay(22.30) if !strings.Contains(msg, "paid using debit card") { t.Error("The debit card payment method message was't correct") } t.Log("LOG: ", msg) } func TestGetPaymentMethodNonExistent(t *testing.T) { _, err := GetPaymentMethod(20) if err == nil { t.Error("A payment mothod with ID 20 must return an error") } t.Log("LOG:", err) }