In most of our Go courses, we encourage the use of the standard library's testing package, and tend to use table-driven tests... but ThePrimeagen (ex-Netflix btw) has a different preferred approach, so we'll roll with that for this course!
No complex logic in my tests, please!!! I'll explain my approach below.
Point #3 is why I tend to use testify and avoid the loops required for table-driven tests. This is what the test suite looked like in Lane's way of doing things:
tests := []struct {
name string
request string
wantMethod string
wantTarget string
wantVersion string
wantErr bool
}{
// test cases here...
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
r, err := RequestFromReader(strings.NewReader(tt.request))
if tt.wantErr && err == nil {
t.Fatalf("expected an error, but got none")
return
}
if !tt.wantErr && err != nil {
t.Fatalf("expected no error, but got one")
return
}
if err != nil {
return
} else if err != nil {
t.Fatalf("expected no error, but got: %v", err)
}
if r == nil {
t.Fatalf("expected a request, but got none")
}
if r.RequestLine.Method != tt.wantMethod {
t.Fatalf("got method = %v, want %v", r.RequestLine.Method, tt.wantMethod)
}
if r.RequestLine.RequestTarget != tt.wantTarget {
t.Fatalf("got target = %v, want %v", r.RequestLine.RequestTarget, tt.wantTarget)
}
if r.RequestLine.HttpVersion != tt.wantVersion {
t.Fatalf("got version = %v, want %v", r.RequestLine.HttpVersion, tt.wantVersion)
}
})
I prefer a simple procedural approach:
// Test: Good GET Request line
r, err := RequestFromReader(strings.NewReader("GET / HTTP/1.1\r\nHost: localhost:42069\r\nUser-Agent: curl/7.81.0\r\nAccept: */*\r\n\r\n"))
require.NoError(t, err)
require.NotNil(t, r)
assert.Equal(t, "GET", r.RequestLine.Method)
assert.Equal(t, "/", r.RequestLine.RequestTarget)
assert.Equal(t, "1.1", r.RequestLine.HttpVersion)
// Test: Good GET Request line with path
r, err = RequestFromReader(strings.NewReader("GET /coffee HTTP/1.1\r\nHost: localhost:42069\r\nUser-Agent: curl/7.81.0\r\nAccept: */*\r\n\r\n"))
require.NoError(t, err)
require.NotNil(t, r)
assert.Equal(t, "GET", r.RequestLine.Method)
assert.Equal(t, "/coffee", r.RequestLine.RequestTarget)
assert.Equal(t, "1.1", r.RequestLine.HttpVersion)
Fewer conditionals, fewer things for me to get wrong in my tests.
We'll be working on the request line parser, so let's get our directory structure and test dependency set up.
mkdir -p ./internal/request
go get -u github.com/stretchr/testify/assert
package request
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestRequestLineParse(t *testing.T) {
assert.Equal(t, "TheTestagen", "TheTestagen")
}
Run and submit the CLI tests from the root of your project.