Your project structure isn't the one Go expects.
area_test/
are not the tests for area
. I'm going to guess you ran go test ./area_test
. That tells Go that ./area_test
is a project. It tried to compile area_mock.go
and tried to use area_mock_test.go
and area_suite_test.go
as its tests. The error you got is Go's awkward way of telling you that it did not expect to find a package named *_test
in a project file.
area.go
is also a problem. You have it using package main
, but then try to test with package area_test
. They don't match and Go won't like it. A package directory contains one package. Its tests must use either that package or thatpackage_test
. This enforces that a package directory does one thing. Its either a library to import, or its a program to run. Not both.
Also the project directory is called square
, but the package is area
. It's ok to have files that don't match the project name, and its fine to have multiple files in one package, but using a package than the project directory name is not good practice.
There's another problem. Go expects source files to be in $GOPATH/src
. You have them directly in $GOPATH
. Import statements won't find them.
Go's project structure can take a bit of getting used to, and it has very firm ideas about how projects and packages are to be structured (Go has very firm ideas about how code is to be written, and how it isn't). Don't fight it. Do yourself a favor and use the default GOPATH
of ~/go
and put your code in ~/go/src/
.
You'd write the square library like so.
~/go/src/square/
|--- square.go
|--- square_test.go
square.go might look like this.
package square
type Square struct {
Side float32
}
func (s Square) Area() float32 {
return s.Side * s.Side
}
Note that Side
must be capitalized for it to be a public data member. Also note that its passed by value, in Go the style is to only pass by pointer if you intend to modify the struct.
square_test.go might look like this.
package square_test
import(
"testing"
"square"
"github.com/stvp/assert"
)
func TestArea( t *testing.T ) {
sq := square.Square{Side: 5}
assert.Equal( t, sq.Area(), float32(25) )
}
Go does not come with any asserts. github.com/stvp/assert
provides the basics and removes a lot of tedium. You can get it with go get github.com/stvp/assert
.
Note that it is in package square_test
to make this a blackbox test which can only use the public interface of square
. If you wanted a glassbox/internal test, it would use package square
and go in its own file like square_internal_test.go
.
If you want a program that uses square, that would be in its own separate package directory. It would have a main.go
with package main
and import "square"
.
How To Write Go explains this in more detail.