Skip to content
Permalink
Branch: master
Find file Copy path
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
116 lines (90 sloc) 3.89 KB

Best Practices

  • Prior to all checkins please run gofmt -w yourfile.go (there are many plugins)
  • Packages are given lower case, single-word names; there should be no need for underscores or mixedCaps
  • Interface names and variables Convention in Go is to use MixedCaps or mixedCaps rather than underscores to write multiword names
  • Only functions / variables starting with a capital letter would be usable outside the package. All other internal functions start with lower case
  • There is linter tool https://github.com/golang/lint which recommends “proper” syntax for your programs (cd myProject; golint ./… )
  • Other great tools:
    • errcheck
    • go vet
    • go test -race

Deployment

Manage Go package dependencies using godep https://github.com/tools/godep

Building for Linux on mac

Setup Cross compilation One needs to compile Go compiler for different target platforms and architectures. This is done from src folder in go installation. If you use Homebrew on OS X, then you have a simpler solution: $ brew install go --with-cc-all # All the cross-compilers Then to build: GOOS=linux GOARCH=386 CGO_ENABLED=0 go build -o appname-linux appname.go

Testing

Test tables

We can use anonymous structs to write very clear table tests that have multiple inputs and expected results without relying on any external package. E.g.

var testTable = []struct {
		isdev    bool
		expected string
	}{
		{true, "/Users/"},
		{false, "/home/httpd/"},
	}

	for _, test := range testTable {
		config.IsDev = test.isdev
		actual := getUsersHomeDir()
		if !strings.Contains(actual, test.expected) {
			t.Errorf("getUsersHomeDir: Expected %s, Got %s", test.expected, actual)
		}
	}

Gotchas

Date Formatting

Go just doesn't use an abstract syntax for datetime components (YYYY-MM-DD), but these exact numbers. No other number will do! These are predefined layouts for use in Time.Format and Time.Parse. The reference time used in the layouts is the specific time: Mon Jan 2 15:04:05 MST 2006 which is Unix time 1136239445. Since MST is GMT-0700, the reference time can be thought of as 01/02 03:04:05PM '06 -0700 To define your own format, write down what the reference time would look like formatted your way; see the values of constants like ANSIC, StampMicro or Kitchen for examples. The model is to demonstrate what the reference time looks like so that the Format and Parse methods can apply the same transformation to a general time value.

Maps and struct

Assign a struct field off map has to be done by first creating the element in golang.

/Each node type apiNode struct { method, expectedfile string }

var handlerMap map[string]apiNode handlerMap = make(map[string]apiNode)

handlerMap[APIName] = apiNode{"GET","a.json"}

Mocking

Create the interface with one or more of the methods from the original package struct

E.g. This is so we can mock the sftphelper.SFTPConnection struct

type SftpConnector interface {
	RemoveFile(string) error
}

Write the mock struct using the interface

type FakeSftpConnector struct {
	
}
// make sure it satisfies the interface
var _ SftpConnector = (*FakeSftpConnector)(nil)

func (f *FakeSftpConnector) RemoveFile(source string) error {
...
}

Update your function that takes the sftphelper.SFTPConnection struct function to take the new interface instead

In your test code, you can send in the fake struct instead and make assertions on the inputs after calling the target function

func TestProcessInnerFiles(t *testing.T) {
	tt := &FakeSftpConnector{}
	err := processInnerFiles(tt, "/home/ftptest/feed_20160912/", "IN7994_20160715.json")
	if err != nil {
		t.Errorf("Error was not expected in processInnerFiles: %s", err)
	}
}

Reference Links

You can’t perform that action at this time.