steinfletcher/apitest

Flow Testing in Table driven

TudorHulban opened this issue · 2 comments

Is your feature request related to a problem? Please describe.
Would like to test a flow in a table driven test with Gin. Testing the flow in a table driven test would make the test concise for me.

Describe the solution you'd like

func TestFlow(t *testing.T) {
	tt := []struct {
		name           string
		httpMethod     string
		request        string
		want           string
		statusCodeHTTP int
	}{
		{name: "t1", httpMethod: "GET", request: "/url1", want: `{"r1":128}`, statusCodeHTTP: http.StatusOK},
		{name: "t2", httpMethod: "PUT", request: "/url2", want: ``, statusCodeHTTP: http.StatusOK},
	}

	s := NewHTTPServer("0.0.0.0:8000")

	for _, tc := range tt {
		t.Run(tc.name, func(t *testing.T) {
			apitest.New().
				Handler(s.Engine).
                                (tc.httpMethod).(tc.request).
				Expect(t).
				Status(tc.statusCodeHTTP).
				Body(tc.want).
				End()
		})
	}
}

Below alternative is without chaining and does not look so good:

	for _, tc := range tt {
		t.Run(tc.name, func(t *testing.T) {
			v := apitest.New()
			v.Handler(s.Engine)
			v.Method(tc.httpMethod)
			v.Request().URL(tc.request)
			v.Request().Expect(t)
			v.Response().Status(tc.statusCodeHTTP)
			v.Request().Body(tc.want)
			v.Response().End()
		})
	}

Additional context
Everything works besides changing the HTTP request method and maintaining the nice chaining structure.

How about this @TudorHulban?

func TestApiTest(t *testing.T) {
	tt := map[string]struct {
		httpMethod     string
		request        string
		want           string
		statusCodeHTTP int
	}{
		"test 1": {httpMethod: "GET", request: "/url1", want: `{"r1":128}`, statusCodeHTTP: http.StatusOK},
	}

	for name, test := range tt {
		t.Run(name, func(t *testing.T) {
			handler := http.NewServeMux()
			handler.HandleFunc("/url1", func(w http.ResponseWriter, r *http.Request) {
				w.WriteHeader(http.StatusOK)
				_, _ = w.Write([]byte(`{"r1":128}`))
			})

			apitest.New().
				Handler(handler).
				Method(test.httpMethod).
				URL(test.request).
				Expect(t).
				Status(test.statusCodeHTTP).
				End()
		})
	}
}

Awesome library. It might be worth adding an example with passing the HTTP method in the documentation.

Thank you very much!