LoadGuilds from the guild util class is now tested using a mocked guildLoader
MODIFY
discordutil/guilds.go
discordutil/guilds.go
@@ -6,13 +6,18 @@ import (
"github.com/Bios-Marcel/discordgo"
)
+// GuildLoader reflects an instance that allows loading guilds from a discord backend.
+type GuildLoader interface {
+ UserGuilds(int, string, string) ([]*discordgo.UserGuild, error)
+}
+
// LoadGuilds loads all guilds the current user is part of.
-func LoadGuilds(session *discordgo.Session) ([]*discordgo.UserGuild, error) {
+func LoadGuilds(guildLoader GuildLoader) ([]*discordgo.UserGuild, error) {
guilds := make([]*discordgo.UserGuild, 0)
var beforeID string
for {
- newGuilds, discordError := session.UserGuilds(100, beforeID, "")
+ newGuilds, discordError := guildLoader.UserGuilds(100, beforeID, "")
if discordError != nil {
return nil, discordError
}

MODIFY
discordutil/guilds_test.go
discordutil/guilds_test.go
package discordutil
import (
+ "errors"
+ "fmt"
+ "reflect"
"testing"
"github.com/Bios-Marcel/discordgo"
@@ -46,3 +49,123 @@ func TestSortGuilds(t *testing.T) {
t.Errorf("The fourth guild should've been %s, but was %s", guildFourID, guilds[3].ID)
}
}
+
+type testGuildLoader struct {
+ loadFunction func(int, string, string) ([]*discordgo.UserGuild, error)
+}
+
+func (loader testGuildLoader) UserGuilds(amount int, beforeID, afterID string) ([]*discordgo.UserGuild, error) {
+ return loader.loadFunction(amount, beforeID, afterID)
+}
+
+func generateGuilds(start, amount int) []*discordgo.UserGuild {
+ guilds := make([]*discordgo.UserGuild, 0, amount)
+ for i := start; i < start+amount; i++ {
+ fmt.Println(i)
+ guilds = append(guilds, &discordgo.UserGuild{ID: fmt.Sprintf("%d", i)})
+ }
+
+ return guilds
+}
+
+func TestLoadGuilds(t *testing.T) {
+ type args struct {
+ guildLoader GuildLoader
+ }
+ tests := []struct {
+ name string
+ guildLoader GuildLoader
+ want []*discordgo.UserGuild
+ wantErr bool
+ }{
+ {
+ name: "forward error",
+ guildLoader: testGuildLoader{func(amount int, beforeID, afterID string) ([]*discordgo.UserGuild, error) {
+ return nil, errors.New("owo, an error")
+ }},
+ want: nil,
+ wantErr: true,
+ }, {
+ name: "no guilds",
+ guildLoader: testGuildLoader{func(amount int, beforeID, afterID string) ([]*discordgo.UserGuild, error) {
+ return nil, nil
+ }},
+ want: []*discordgo.UserGuild{},
+ wantErr: false,
+ }, {
+ name: "100 guilds",
+ guildLoader: testGuildLoader{func(amount int, beforeID, afterID string) ([]*discordgo.UserGuild, error) {
+ //100 is the API limit
+ if amount == 100 {
+ if beforeID == "" {
+ return generateGuilds(1, 100), nil
+ } else if beforeID == "1" {
+ return []*discordgo.UserGuild{}, nil
+ }
+
+ return nil, errors.New("unsupported case")
+ }
+
+ return nil, errors.New("test only supports usecase of 100 at once")
+ }},
+ want: generateGuilds(1, 100),
+ wantErr: false,
+ }, {
+ name: "150 guilds",
+ guildLoader: testGuildLoader{func(amount int, beforeID, afterID string) ([]*discordgo.UserGuild, error) {
+ //100 is the API limit
+ if amount == 100 {
+ if beforeID == "" {
+ return generateGuilds(51, 100), nil
+ } else if beforeID == "51" {
+ return generateGuilds(1, 50), nil
+ }
+
+ return nil, errors.New("unsupported case")
+ }
+
+ return nil, errors.New("test only supports usecase of 100 at once")
+ }},
+ want: generateGuilds(1, 150),
+ wantErr: false,
+ }, {
+ name: "200 guilds",
+ guildLoader: testGuildLoader{func(amount int, beforeID, afterID string) ([]*discordgo.UserGuild, error) {
+ //100 is the API limit
+ if amount == 100 {
+ if beforeID == "" {
+ return generateGuilds(101, 100), nil
+ } else if beforeID == "101" {
+ return generateGuilds(1, 100), nil
+ } else if beforeID == "1" {
+ return []*discordgo.UserGuild{}, nil
+ }
+
+ return nil, errors.New("unsupported case")
+ }
+
+ return nil, errors.New("test only supports usecase of 100 at once")
+ }},
+ want: generateGuilds(1, 200),
+ wantErr: false,
+ },
+ }
+
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ got, err := LoadGuilds(tt.guildLoader)
+ if (err != nil) != tt.wantErr {
+ t.Errorf("LoadGuilds() error = %v, wantErr %v", err, tt.wantErr)
+ return
+ }
+
+ if len(got) != len(tt.want) {
+ t.Errorf("length of LoadGuilds() = %v, want %v", len(got), len(tt.want))
+ }
+
+ if !reflect.DeepEqual(got, tt.want) {
+ t.Errorf("LoadGuilds() = %v, want %v", got, tt.want)
+ }
+ })
+ }
+}

LoadGuilds from the guild util class is now tested using a mocked guildLoader