March 22, 2015

Learning Golang with Testing

Over the past week I have been learning A LOT of golang. In order to do that, I need to set up a few things to create a Rest API, the SDK, environment, IDE, Debugger, Testing and code. I’ll show you what I ran into…

Installation and Environment

First, go grab Go from here: download page. You shouldn’t have an problems installing it, outside of having to set up GOPATH environmental variable. PLEASE GO DO THAT.

Protip: if you are looking on line for information about GO, don’t just type GO, type GOLANG.

The GOPATH is super important because it tells GO where all your GO code is going to live. This means your binaries that are shared, code from other repositories, EVERYTHING! This is because GO is a compiled language. If you have done some C++ coding, linker libraries and directories use to be a HUGE pain. While I think this has been resolved by most modern programming languages, it is nice to know that all my code is in one location. I put my go path here -> ~/git/GO .

Sweet, now you can do some Golang, but you will need an IDE…

IDE

While you can use Sublime Text, Atom, or whatever editor you want, there is an open source editor called LiteIDE. LiteIDE is an editor specifically designed for GO and might serve you well. It does syntax highlighting, intellisense and even autocomplete. To install, be sure to have homebrew, brew cask and try these commands:

 brew install brew-cask # This installs an extension for brew brew cask install liteide # This installs the IDE 

Debugging

LiteIDE, as well as others, can debug using GDB. If you have done some C++ using G++ or GCC, then you should be familiar with this tool. If not, use brew to install gdb. Even better, we can embed the tool into LiteIDE to get some debugging in the editor. To do this, you have to get GDB to trust LiteIDE, which is all explained in this article here: Under Step 6. If this is on a mac, you may have to trust some certs, so check out this article as well: http://www.opensource.apple.com/source/lldb/lldb-69/docs/code-signing.txt.

Protip: While there is a debugger, gdb is very unstable and kinda sucks for GO. I would suggest utilizing unit tests to find out if code is working the way you want.

Testing and Coding

Now, you should have your environment set up, and probably wrote a hello world app. Let’s try for a Rest API. First, start off with a main.go file:

 package main import ( "log" "net/http" ) func main() { router := NewRouter() log.Fatal(http.ListenAndServe(":8080", router)) } 

What we have here is a router, which will create a routes, then listen to port 8080. Let’s build our route.go file:

 package main import ( "github.com/gorilla/mux" "net/http" ) type Route struct { Name string Method string Pattern string HandlerFunc http.HandlerFunc } type Routes []Route func NewRouter() \*mux.Router { router := mux.NewRouter().StrictSlash(true) for \_, route := range routes { router. Methods(route.Method). Path(route.Pattern). Name(route.Name). Handler(route.HandlerFunc) } return router } var routes = Routes{ Route{ "GetData", "GET", "/api/data", Get\_Data, }, } 

So, this shows us how to create a list of routes, and then how the router adds them to the route table. If you look at the routes array, each element should have a Name, a Verb, a Route and a handler (callback function). One last thing, the import at the top says github. So long as you have the repository system installed, whether github or mecurial, GO will automatically pull down that dependency and build it for you. The next file we will need to make is the handler, so let’s make a handler.go file:

 package main import ( "encoding/json" "net/http" ) func Get\_Data(response http.ResponseWriter, request \*http.Request) { json.NewEncoder(response).Encode("{ 'msg':'Hello World' }") } 

With this code, when we call ‘/api/data’, we will get back a json message saying hello world. Noticed that we have a response writer (stream) and a request object. These are the 2 things you will need to complete a web call. Let’s talk about some Unit testing.

Unit testing follows some conventions, like usually the name of the file under test with an underscore test. Example, handlers\_test.go . Let’s go ahead and make a unit test for our handlers.go file called handlers\_test.go:

 package main import ( "net/http/httptest" "testing" ) func TestHelloWorld\_Ok(t \*testing.T) { var response = httptest.NewRecorder() Get\_Data(response, nil) if response.Code != 200 { t.Errorf("Should have 200 status code. Response Code: %v", response.Code) } if response.Body.String() != "{ 'msg':'Hello World' }" { t.Errorf("Should have had a hello world. Body: %v", response.Body.String()) } } 

What we have here is a test that mocks up request to Get\_Data. We look at the response and see what the status code is and the body. The tests should always start with Test and have a \*testing.T passed into the function.

Protip: Be sure to include the value in your error, so you can know why the test failed.

That is my quick list of things to help you get going on your GOLANG project. If you want a larger REST service to check out, you can check out the service I have here: https://github.com/supermitsuba/RestApiDiscovery and here are some more links:

 http://thenewstack.io/make-a-restful-json-api-go/ https://gobyexample.com/