I'm trying to test an implementation of a simple web server in Go using the Gin.
The service has a single endpoint rendering HTML.
server.go
// Serve triggers the server initialization
func Serve(addr string) {
if err := serverEngine().Run(addr); err != nil {
log.Fatalf("could not serve on %s: %s", addr, err)
}
}
func serverEngine() *gin.Engine {
eng := gin.Default()
// Register resource handlers
eng.LoadHTMLGlob("tmpl/*")
eng.GET("/", indexHandler)
return eng
}
func indexHandler(c *gin.Context) {
c.HTML(http.StatusOK, "index.tmpl", gin.H{
"title": "foo",
})
}
server_test.go
func TestServe(t *testing.T) {
timeOut := time.Duration(3) * time.Second
server := httptest.NewServer(serverEngine())
defer server.Close()
// fixes weird double ':' problem
port := server.URL[len(server.URL)-5:]
_, err := net.DialTimeout("tcp", "localhost:"+port, timeOut)
if err != nil {
t.Errorf("failed to dial server: %s", err)
}
}
When I run the code everything works fine. But when running the unit tests it panics with the following message:
--- FAIL: TestServe (0.00s)
panic: html/template: pattern matches no files: `tmpl/*` [recovered]
panic: html/template: pattern matches no files: `tmpl/*`
Project structure:
.
├── main.go
└── server
├── server.go
├── server_test.go
└── tmpl
└── index.tmpl
How can I ensure that the go test
know about the template location at runtime so I can perform this test?
EDIT:
After comment interaction, updating answer match directory structure.
gin-test/
├── main.go
└── server
├── server.go
├── server_test.go
└── tmpl
└── index.tmpl
And your server.go file on function serverEngine()
has-
eng.LoadHTMLGlob("tmpl/*")
First you're in root directory: i.e. gin-test
, run-
# Output:
jeeva@mb-pro:~/go-home/src/gin-test$ go test ./...
? gin-test [no test files]
ok gin-test/server 0.046s
Second you're in gin-test/server
directory/package:
jeeva@mb-pro:~/go-home/src/gin-test/server$ go test
#Output:
It would produce the same output as below answer.
My best guess is 'problem could be your directory structure and files' and bit of test case code improvements.
I have just tried your code at my local with following directory structure:
$GOPATH/src/gin-test/
├── server.go
├── server_test.go
└── tmpl
└── index.tmpl
Then, I have updated your TestServe
method to following:
Note: your test case works too, I just updated to demo the GET request and response.
func TestServe(t *testing.T) {
server := httptest.NewServer(serverEngine())
defer server.Close()
fmt.Println("Server URL:", server.URL)
resp, err := http.Get(server.URL)
body, _ := ioutil.ReadAll(resp.Body)
fmt.Println("Error:", err)
fmt.Println("Response:", string(body))
}
Unit test output:
jeeva@mb-pro:~/go-home/src/gin-test$ go test
[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
- using env: export GIN_MODE=release
- using code: gin.SetMode(gin.ReleaseMode)
[GIN-debug] Loaded HTML Templates (1):
- index.tmpl
[GIN-debug] GET / --> gin-test.indexHandler (3 handlers)
Server URL: http://127.0.0.1:56989
[GIN] 2017/07/09 - 16:31:16 | 200 | 432.107µs | 127.0.0.1 | GET /
Error: <nil>
Response: <b>I'm here</b>
PASS
ok gin-test 0.104s
jeeva@mb-pro:~/go-home/src/gin-test$
Happy coding!