Master Go Unit Testing: From Basics to Mocking with GoConvey
This article explains what unit testing is, shows how to write Go unit tests using the testing package, demonstrates more expressive assertions with GoConvey, and introduces mock creation with mockery, providing practical code examples and best‑practice tips for backend developers.
What is Unit Testing?
In computing, unit testing (also called module testing) verifies the correctness of individual program modules, which are the smallest testable parts of an application.
How to Write Unit Tests in Go
Go's testing framework uses files ending with _test.go . The go test command compiles and runs these files. Key elements include naming test files, using TestMain with a testing.M parameter, writing test functions in the form TestXXX(t *testing.T), running all tests with go test, and targeting specific tests with go test -v -run TestFunctionName.
func TestUser(t *testing.T) {
var u = &User{Age: 15, Name: "alice"}
if u.Age != 15 {
t.Error("age err")
}
if u.Name != "bob" {
t.Error("name err")
}
}The test runs and reports failures when expectations are not met.
Using GoConvey for Better Assertions
GoConvey adds convenient setup/teardown and a rich set of So assertions, producing clearer failure messages.
func TestUser(t *testing.T) {
convey.Convey("TestUser", t, func() {
var u = &User{Age: 15, Name: "alice"}
convey.So(u.Age, convey.ShouldEqual, 15)
convey.So(u.Name, convey.ShouldEqual, "bob")
})
}Mocking in Go with mockery
When unit tests involve third‑party dependencies, mocking replaces those interfaces with controllable fakes. The mockery tool generates mocks for Go interfaces.
// client.go
package rpc
//go:generate mockery -name=Client
type Client interface {
Get(key string) (data interface{}, err error)
}
type ClientImpl struct {
Ct Client
}
func (p *ClientImpl) Get(key string) (data interface{}, err error) {
if mockCondition {
return p.Ct.Get(key)
}
// real logic
} // client_test.go
package rpc
import (
"testing"
"github.com/stretchr/testify/mock"
"github.com/smartystreets/goconvey/convey"
)
type User struct {
Age int
Name string
}
func TestMock(t *testing.T) {
convey.Convey("TestMock", t, func() {
mc := &mocks.Client{}
var u = &User{Age: 15, Name: "alice"}
mc.On("Get", "alice").Return(u, nil)
ci.Ct = mc
data, err := ci.Get("alice")
convey.So(data.Age, convey.ShouldEqual, 15)
})
}Conclusion
Unit testing is an essential part of software quality; aiming for high coverage reduces bugs and improves code understanding. Using tools like GoConvey and mockery makes tests more expressive and maintainable.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
NiuNiu MaTe
Joined Tencent (nicknamed "Goose Factory") through campus recruitment at a second‑tier university. Career path: Tencent → foreign firm → ByteDance → Tencent. Started as an interviewer at the foreign firm and hopes to help others.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
