-
Notifications
You must be signed in to change notification settings - Fork 1
/
dogservice_test.go
134 lines (111 loc) · 3.91 KB
/
dogservice_test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
package gotoproduction_test
import (
"context"
"github.com/amammay/gotoproduction"
"github.com/amammay/gotoproduction/internal/logx"
"github.com/amammay/gotoproduction/internal/testx"
"github.com/matryer/is"
"github.com/testcontainers/testcontainers-go"
"testing"
)
// integration testing a service with a db interaction
func TestDogService(t *testing.T) {
// skip test if docker is not available, very important that go test always work!
testcontainers.SkipIfProviderIsNotHealthy(t)
ctx := context.Background()
// set up out testing container
fsContainer, err := testx.CreateFirestoreContainer(ctx)
if err != nil {
t.Fatalf("createFirestoreContainer() err = %v; want nil", err)
}
// run a clean up method to terminate the container when this test and all sub tests are completed
t.Cleanup(func() {
err := fsContainer.Terminate(ctx)
if err != nil {
t.Fatalf("fsContainer.Terminate() err = %v; want nil", err)
}
})
// cool way to dynamically allocate an endpoint for us to use, we could have multiple integration test running in parallel that would never have a port collision
endpoint, err := fsContainer.Endpoint(ctx, "")
if err != nil {
t.Errorf("fsContainer.Endpoint() err = %v; want nil", err)
}
// home made firestore testing client that has a util method for clearing all data
fsClient := testx.NewFirestoreTestingClient(ctx, t, endpoint)
service := gotoproduction.NewDogService(fsClient.Client, logx.NewTesterLogger(t))
t.Run("Create", testDogService_CreateDog(service, fsClient))
t.Run("Find By Type", testDogService_FindDogByType(service, fsClient))
t.Run("GetDog By ID", testDogService_GetDogByID(service, fsClient))
}
// simple test case, just creates a dog
func testDogService_CreateDog(ds *gotoproduction.DogService, fsClient *testx.FsTestingClient) func(t *testing.T) {
return func(t *testing.T) {
fsClient.ClearData(t)
ctx := context.Background()
is := is.New(t)
createDogRequest := &gotoproduction.CreateDogRequest{
Name: "Oscar",
Age: 1,
Type: "Golden Doodle",
}
dog, err := ds.CreateDog(ctx, createDogRequest)
is.NoErr(err) // ds.CreateDog error
got := len(dog)
want := 20
is.Equal(got, want) // must have a document id
}
}
// a bit more complex test case, creates a dog and then attempts to find that dog we created
func testDogService_FindDogByType(ds *gotoproduction.DogService, fsClient *testx.FsTestingClient) func(t *testing.T) {
return func(t *testing.T) {
fsClient.ClearData(t)
ctx := context.Background()
is := is.New(t)
createDogRequest := &gotoproduction.CreateDogRequest{
Name: "Oscar",
Age: 1,
Type: "Golden Doodle",
}
_, err := ds.CreateDog(ctx, createDogRequest)
is.NoErr(err) // ds.CreateDog error
byType, err := ds.FindDogByType(ctx, createDogRequest.Type)
is.NoErr(err) // ds.FindDogByType error
got := len(byType)
want := 1
is.Equal(got, want) // must find one dog by type
}
}
// table driven test example, create a dog then attempt to find it by its ID, also test to see if our custom error is thrown when it cant find the dog by id
func testDogService_GetDogByID(ds *gotoproduction.DogService, fsClient *testx.FsTestingClient) func(t *testing.T) {
return func(t *testing.T) {
fsClient.ClearData(t)
ctx := context.Background()
is := is.New(t)
createDogRequest := &gotoproduction.CreateDogRequest{
Name: "Oscar",
Age: 1,
Type: "Golden Doodle",
}
createDog, err := ds.CreateDog(ctx, createDogRequest)
is.NoErr(err) // ds.CreateDog error
tests := []struct {
args string
want *gotoproduction.Dog
wantErr error
}{
{args: createDog, wantErr: nil},
{args: "999", wantErr: gotoproduction.ErrDogNotFound},
}
for _, tt := range tests {
t.Run(tt.args, func(t *testing.T) {
is := is.New(t)
_, err := ds.GetDogByID(ctx, tt.args)
if tt.wantErr != nil {
is.Equal(tt.wantErr, err) // not matching errors
return
}
is.NoErr(err) // ds.GetDogByID error
})
}
}
}