1

I'm writing a simple webserver in golang that gets/creates/edits/deletes a simple text file. I've written the function handlers and I'd like to test them by sending a request to the appropriate url and checking to see what happens. My code is as below:

func createHandler(w http.ResponseWriter, r *http.Request) {
    vars := mux.Vars(r)
    name := vars["name"]
    body, _ := ioutil.ReadAll(r.Body)
    fmt.Fprint(w, name)
    ioutil.WriteFile(name, []byte(body), 0644)
}

func main() {
    r := mux.NewRouter()
    r.HandleFunc("/textFiles/{name}", createHandler).Methods("POST")
    log.Fatal(http.ListenAndServe(":8080", r))

    var url = "http://localhost:8080/textFiles/testFile.txt"
    var text = []byte(`{"title":"this is an example."}`)
    req, err := http.NewRequest("POST", url, bytes.NewBuffer(text))
    if err != nil {
        panic(err)
    }

    client := &http.Client{}
    client.Do(req)
}

Once this code is run, however, no new file is created. I've been googling but I can't find anything on this type of problem, where I'm sending a request to the server that I'm building within the same file. Help appreciated.

2
  • 3
    you don't check errors from ioutil.WriteFile. You ignore errors from ioutil.ReadAll either. Out of curiosity, does this program ever finish? http.ListenAndServe is blocking isn't it? Commented Feb 26, 2019 at 20:03
  • 1
    The reason you haven't found much information about it is because it's a very unusual way to test something. Tests should be in tests, using the testing package, not in main(). Tests of HTTP services should use httptest. Commented Feb 26, 2019 at 20:16

1 Answer 1

3

The client code is not executed. The callhttp.ListenAndServe(":8080", r) runs the server. The function only returns when there was an error running the server. If the function does return, then log.Fatal will exit the process.

One fix is to run the server in a goroutine. This will allow main goroutine to continue executing to the client code.

go func() {
    log.Fatal(http.ListenAndServe(":8080", r))
}()

This may not fix the problem because there's no guarantee that server will run before the client makes the request. Fix this issue by creating the listening socket in the main function and running the server in a goroutine.

ln, err := net.Listen("tcp", ":8080")
if err != nil {
    log.Fatal(err)
}
go func() {
    log.Fatal(http.Serve(ln, r))
}()
... client code as before

If the goal if this code is testing, then use httptest.Server. The example in the documentation show show to use the test server.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.