Golang ทำ Unit test http ด้วย httptest กันหน่อย (ทำ ทำไมนะ)

Kawee Lertrungmongkol
odds.team
Published in
2 min readFeb 1, 2019

อยากรู้ว่า Go เรียก api ยังไงนะ แล้วทดสอบยังไงได้บ้าง ลองหาข้อมูลก็เจอว่า go ใช้ net/http ในการ call api และใช้ net/httptest (จำลองตัวเองเป็น server อารมณ์ stubby4j) ในการทดสอบ แต่ก็ยังมีคำถามในใจ เอ่….??ใช้ยังไง ใช้ได้จริงรึเปล่า ทดสอบยากไหม ลองดูกัน

โจทย์

  • ค้นหาข้อมูล github user ด้วยการ เรียก github api (rest api)ที่ url https://api.github.com/users/${username}
  • ไม่พบข้อมูลให้ display error msg เช็คจาก http status
  • format ของข้อมูลผิดให้ display error msg
  • พบข้อมูลให้เอามา display

มาเริ่มกันเลย

สร้าง

  • interface ที่มี method ที่ชื่อว่า GetUserInfo
  • struct สำหรับ mapping data

implement method GetUserInfo ตามโจทย์

หน้าตาประมาณนี้

หน้าตาพอใช้ได้แล้ว ยังไม่รู้นะว่า code ชุดนี้ใช้งานได้รึยัง(สร้าง main ลองเรียกใช้ดูก่อนได้เลย) ต่อไปมาทดสอบกัน วิธีทดสอบ net/http golang เค้ามี net/httptest มาไว้ให้ทดสอบอยู่แล้ว เขียน test case ตามโจทย์ไปเลย หน้าตาก็จะประมาณนี้

case : Test_GetUserInfo_not_found

ทดสอบกัน ของเราได้หน้าตาประมาณนี้ จากนั้นก็ทำไปเรื่อยๆที่ละ case ให้ test ค่อยๆโตขึ้นไป

go test -v ./...
=== RUN Test_GetUserInfo_not_found
--- PASS: Test_GetUserInfo_not_found (0.00s)
PASS
ok command-line-arguments 0.020s

case : Test_GetUserInfo_fail_with_binding_error

go test -v ./...
=== RUN Test_GetUserInfo_not_found
--- PASS: Test_GetUserInfo_not_found (0.00s)
=== RUN Test_GetUserInfo_fail_with_binding_error
--- PASS: Test_GetUserInfo_fail_with_binding_error (0.00s)
PASS
ok command-line-arguments 0.015s

case : Test_GetUserInfo_Success

go test -v ./...
=== RUN Test_GetUserInfo_not_found
--- PASS: Test_GetUserInfo_not_found (0.00s)
=== RUN Test_GetUserInfo_fail_with_binding_error
--- PASS: Test_GetUserInfo_fail_with_binding_error (0.00s)
=== RUN Test_GetUserInfo_Success
--- PASS: Test_GetUserInfo_Success (0.00s)
PASS
ok command-line-arguments 0.017s

หลังจากทดสอบได้ครบตามโจทย์ มาลองเรียกจริงๆกันดูดีกว่าว่ามันใช้ได้รึเปล่า

build & run …..

go build -o run
./run
ดูดี

สรุป

net/http ใช้เรียก api ได้โดยใช้ net/httptest ทดสอบได้ หากถามว่าจำเป็นต้องทำ unit test ไหมในกรณีนี้(ต้องการแค่เรียก api แล้ว return response ออกมา) เราคิดว่าไม่จำเป็นต้องทำก็ได้เพราะ ไม่ได้มี logic ใดๆซับซ้อน

การทำ integration test จะตอบโจทย์กว่า หากมีการปรับ api โดยที่ไม่มีการแจ้งเตือน เราจะรู้ได้ทันทีที่ผลการทดสอบออกมา เมื่อรู้เร็วเราจะสามารถหาวิธีรับมือได้ เร็วเช่นกัน

--

--