1

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?

Alessandro Resta
  • 1,102
  • 1
  • 19
  • 26

1 Answers1

0

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!

jeevatkm
  • 4,571
  • 1
  • 23
  • 24
  • On my server.go I have `eng := gin.Default()` `eng.LoadHTMLGlob("tmpl/*") ` If I move the template from the project root directory to inside of server folder, it passes the test but fails when I try to run the program. No matter if I change the `eng.LoadHTMLGlob("tmpl/*") ` to `server/tmpl/*` – Alessandro Resta Jul 10 '17 at 07:52
  • Similar problem here: https://stackoverflow.com/questions/23847003/golang-tests-and-working-directory – Alessandro Resta Jul 10 '17 at 07:57
  • Can you please update your directory structure in the question? Typically Go source file and test file resides in same directory. When you pass `tmpl/*` this pattern, it means relative to current directory. I cannot say the SO post you shared related with your problem. – jeevatkm Jul 10 '17 at 08:01
  • As per your directory structure test will run correctly. I'm updating answer further details. – jeevatkm Jul 10 '17 at 08:11
  • @AlessandroResta Did you get a chance to look at answer updates? – jeevatkm Jul 10 '17 at 17:35
  • didn't work =/ but I've found a solution @ https://stackoverflow.com/questions/38320920/how-to-specify-path-of-template-for-app-engine-with-go-for-unit-testing – Alessandro Resta Jul 31 '17 at 14:10