-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathexternal_server_test.go
More file actions
122 lines (91 loc) · 3.38 KB
/
external_server_test.go
File metadata and controls
122 lines (91 loc) · 3.38 KB
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
package httpsteps_test
import (
"bytes"
"io"
"net/http"
"sync"
"testing"
"time"
"github.com/cucumber/godog"
"github.com/godogx/httpsteps"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/swaggest/assertjson"
)
func TestRegisterExternal(t *testing.T) {
es := httpsteps.NewExternalServer()
someServiceURL := es.Add("some-service")
anotherServiceURL := es.Add("another-service")
assert.NotNil(t, es.GetMock("some-service"))
out := bytes.NewBuffer(nil)
suite := godog.TestSuite{
ScenarioInitializer: func(s *godog.ScenarioContext) {
es.RegisterSteps(s)
s.Step(`^I call external services I receive mocked responses$`,
callServices(t, someServiceURL, anotherServiceURL))
},
Options: &godog.Options{
Format: "pretty",
Output: out,
NoColors: true,
Strict: true,
Paths: []string{"_testdata/ExternalServer.feature"},
Randomize: time.Now().UTC().UnixNano(),
},
}
assert.Equal(t, 1, suite.Run())
assert.Contains(t, out.String(), "Error: after scenario hook failed:")
assert.Contains(t, out.String(), "undefined response (missing `responds with status <STATUS>` step) in some-service for GET /never-called")
assert.Contains(t, out.String(), "expectations were not met for another-service: there are remaining expectations that were not met: POST /post-something")
}
func callServices(t *testing.T, someServiceURL, anotherServiceURL string) func() {
t.Helper()
return func() {
// Hitting `"some-service" receives "GET" request "/get-something?foo=bar"`.
req, err := http.NewRequest(http.MethodGet, someServiceURL+"/get-something?foo=bar", nil)
require.NoError(t, err)
req.Header.Set("X-Foo", "bar")
resp, err := http.DefaultTransport.RoundTrip(req)
require.NoError(t, err)
assert.Equal(t, "foo", resp.Header.Get("X-Bar"))
respBody, err := io.ReadAll(resp.Body)
require.NoError(t, resp.Body.Close())
require.NoError(t, err)
assertjson.Equal(t, []byte(`{"key":"value"}`), respBody, string(respBody))
wg := sync.WaitGroup{}
for i := 0; i < 10; i++ {
wg.Add(1)
go func() {
defer wg.Done()
// Hitting `"another-service" receives "POST" request "/post-something" with body`.
req, err := http.NewRequest(http.MethodPost, anotherServiceURL+"/post-something", bytes.NewReader([]byte(`{"foo":"bar"}`)))
assert.NoError(t, err)
resp, err := http.DefaultTransport.RoundTrip(req)
assert.NoError(t, err)
respBody, err := io.ReadAll(resp.Body)
assert.NoError(t, resp.Body.Close())
assert.NoError(t, err)
assertjson.Equal(t, []byte(`{"theFooWas":"bar"}`), respBody)
}()
}
wg.Wait()
// Hitting `"some-service" responds with status "OK"`.
req, err = http.NewRequest(http.MethodGet, someServiceURL+"/no-response-body", nil)
require.NoError(t, err)
resp, err = http.DefaultTransport.RoundTrip(req)
require.NoError(t, err)
respBody, err = io.ReadAll(resp.Body)
require.NoError(t, resp.Body.Close())
require.NoError(t, err)
require.Empty(t, respBody)
// Hitting `"some-service" responds with status "OK" and body`.
req, err = http.NewRequest(http.MethodGet, someServiceURL+"/ask-for-foo", nil)
require.NoError(t, err)
resp, err = http.DefaultTransport.RoundTrip(req)
require.NoError(t, err)
respBody, err = io.ReadAll(resp.Body)
require.NoError(t, resp.Body.Close())
require.NoError(t, err)
assertjson.Equal(t, []byte(`"foo"`), respBody)
}
}