I'm working on a terminal game based on this card game that gets its cards from deckofcardsapi.com. Cards are stored in a struct named Card
in a package called card
and each Card
is stored in a struct called Board
inside an external package called board
. Since Card
has to make requests to the external API my plan is to create Card
fakes with interfaces for testing Board
board properties such as isFull
and errors that panic the program when a user tries to put a card on a full or non existent field.
This is my first project in Go but I've already got experience with Python, mocking and unit testing. I'd like to create Card
fakes without any interface parameter but all examples I've seen on the Internet include a parameter that I think is follows the principle Accept everything, return structs or something like that. I've read Go for devops testing framework and Go workshop interfaces chapter on packtpub plus lots of research on the Internet that usually showed me complex examples that left me confused. As a newly Go adopter my question is: How can mock an external package struct that depends on HTTP request using fakes and interfaces?
This is my code:
board/board_test.go
package board
import (
"errors"
"poker_squares/card"
"testing"
)
type fakeCard struct {
data card.Card
err bool
}
func (c fakeCard) Card() (card.Card, error) {
if c.err {
return "", errors.New("Couldn't create card")
}
return c.data, nil
}
func TestBoard(t *testing.T) {
tests := []struct {
desc string
board Board
want string
expectError bool
}{
{
desc: "Add a card, board isn't full and isFull property is false",
expectError: false,
},
# Remove the rest of tests for brevity
}
}
card/card.go
package card
type CardGetter interface {
Card() (Card, error)
}
type Card struct {
value string
suit string
}
func(c Card)()(Card, error){
# Fetch card from deckofcards API
}
I only had to implement CardGetter
interface in my code the following to fake Card
:
type fakeCard struct {
card Card
err bool
}
func (c fakeCard) Card() (*Card, error) {
values := []string{"2", "3", "4", "5", "6", "7", "8", "9", "J", "Q", "K", "A"}
suit := []string{"HEARTS", "SPADES", "CLUBS", "DIAMONDS"}
card := Card{Value: values[rand.Intn(len(values))], Suit: suit[rand.Intn(len(suit))]}
if c.err {
return nil, errors.New("Couldn't create card")
}
return &card, nil
}
Hope that this answer helps other beginners like me in the future