Write a Unit Test with Ginkgo and Gin

Wasin Wachirapusitanun
odds.team
Published in
2 min readApr 26, 2024

สวัสดีเราโจ้เอง เพิ่งมาเริ่มเขียน Golang เป็นครั้งแรก มีหลายอย่างที่ได้เรียนรู้เลย

และเพิ่งได้ความรู้ใหม่อีกอย่างในการเขียน Unit Test ของ Golang โดยใน Project นี้เราใช้ Ginkgo Package ในการทำ Unit Test และ Go Gin ในการสร้าง CRUD

ซึ่งเขียนคล้ายกับ Jest ที่เราเคยเขียนบน Node.js กันเลย มี Describe และ It เหมือนกันเลย

เราสามารถ Install Ginkgo Package ได้ตาม Command ด้านล่างเลย

go install github.com/onsi/ginkgo/v2/ginkgo

ข้อดีของ Ginkgo คือมีตัว Generate Test File ให้ด้วย สมมติว่าเรามี Package ที่ชื่อว่า User

cd path/to/user
ginkgo bootstrap

คำสั่ง bootstrap จะสร้าง File ขึ้นมาชื่อว่า user_suite_test.go ภายใต้ user_test package

จากนั้นเราจะทำการสร้าง Unit Test สำหรับการ GetUserProfile ขึ้นมา โดยที่ Function นี้สามารถใช้ Context ของ Gin ในการ Return Result ได้เลย

User Service File

func GetUserProfile(context *gin.Context, id string) User {
var userDetails User
for _, user := range mockUsers {
if user.Id == id {
context.IndentedJSON(http.StatusOK, user)
userDetails = user
}
}

context.IndentedJSON(http.StatusNotFound, gin.H{"message": "Not found user"})
return userDetails
}

User Test File

var _ = Describe("Get user profile", func() {
It("should return Somchai Jaidee profile", func(context SpecContext) {
// Mockup gin context
var context *gin.Context

// Mock user id
var userId string = "a2486b53-623c-4b22-9888-24aa5b5e22d9"

// Call get user profile function
userData := user.GetUserProfile(context, userId)

// Expect results
Expect(userData.FirstName).To(Equal("Somchai"))
Expect(userData.LastName).To(Equal("Jaidee"))
})
})

หลังจากที่เราเขียน Unit Test เสร็จให้ลอง Run เพื่อดูว่า Test ผ่านไหม

ginkgo ./...

จะพบว่า Go Panick เนื่องจากว่า gin context ที่เราทำการใส่เข้าไป เป็น Context เปล่า ที่ไม่มีอะไรด้านใน ทำให้เกิด Error แล้วไม่สามารถ Run Function นั้นต่อได้

วิธีการที่จะแก้คือ เปลี่ยน Mode ของ Gin ให้เป็น Test Mode และ Set Test Context ของ Gin เข้าไป

var _ = Describe("Get user profile", func() {
It("should return Somchai Jaidee profile", func(context SpecContext) {
// Mockup gin context
gin.SetMode(gin.TestMode)

headerMockup := httptest.NewRecorder()
context, _ := gin.CreateTestContext(headerMockup)

// Mock user id
var userId string = "a2486b53-623c-4b22-9888-24aa5b5e22d9"

// Call get user profile function
userData := user.GetUserProfile(context, userId)

// Expect results
Expect(userData.FirstName).To(Equal("Somchai"))
Expect(userData.LastName).To(Equal("Jaidee"))
})
})

จากนั้นเรา ทำการ Run Test อีกครั้ง

เท่านี้เราก็จะ Test ผ่านกันแล้ว 🎉🎉🎉🎉🎉🎉🎉

--

--

Wasin Wachirapusitanun
odds.team

I'm a Software Engineer. I wanna improve the software to easily understand and easily to maintain