จากการแบ่งปันเรื่องการพัฒนาระบบงานด้วย Spring Boot และ Testing
มีคำถามเกี่ยวกับ Spring Boot Testing
จึงทำการสรุปความรู้พื้นฐานไว้นิดหน่อยดังนี้
มาเริ่มกันเลย
Spring Boot testing นั้นจะมีให้กับ project ที่สร้างจาก Spring Initalizr
[gist id="4b03d0f7a64d4ce2989d791aa22b108d" file="pom.xml"]ซึ่งจะทำการจัดการ dependency ต่าง ๆ ให้แบบอันโนมัติ
ประกอบไปด้วย
- JUnit 5 คือ testing framework สำหรับภาษา Java ตัวนี้สำคัญสุด ๆ
- Spring Test และ Spring Boot Test ตัวนี้ Spring Boot เตรียมไว้ให้ ใช้งานง่าย ๆ เป็น integration test นั่นเอง ช้าหน่อย แต่ชัวร์
- Mockito สำหรับการจำลอง dependency ต่าง ๆ ใช้ทั้งแบบ unit test และ integration test กับ Spring Boot
- Hamcrest สำหรับการ assert หรือตรวจสอบผลการทำงาน
- AssertJ เหมือนกับ Hamcrest นั่นเอง เลือกได้ตามความชอบ
- JSONAssert สำหรับการตรวจสอบข้อมูลในรูปแบบ JSON ทั้ง object และ array
- JsonPath สำหรับการเข้าถึง property ต่าง ๆ ใน JSON
ถ้าต้องการ test ในรูปแบบอื่น ๆ ก็ต้องเพิ่ม dependency เพิ่ม เช่น
- WireMock สำหรับจำลอง external api ใช้งาน Contract Stub Runner
- Test container สำหรับทำงานร่วมกับ docker container
มาดูรายละเอียดของ 4 สิ่งที่น่าสนใจ
เรื่องที่ 1 :: JUnit 5
เป็น testing framework สำหรับ Java ซึ่งมีโครงสร้างหลัก ๆ ดังนี้
[gist id="4b03d0f7a64d4ce2989d791aa22b108d" file="1.java"]เรื่องที่ 2 :: Spring Boot testing
ทาง Spring Boot นั้นได้เตรียมไว้ให้
ซึ่งเป็น integration test นั่นเอง โดยสิ่งที่เตรียมไว้ให้มีดังนี้
- Spring Boot Testing สำหรับ start web server และชุดการทดสอบต่าง ๆ ไว้ให้ ทำงานเหมือนจริงทุกอย่าง เป็นตัวแทนของจริงได้เลย ว่าถ้าทดสอบผ่านแล้ว จะ run ได้ตามที่ต้องการแน่นอน แต่ข้อเสียคือ ช้าที่สุด
ตัวอย่างการใช้งานง่าย ๆ เป็นการทดสอบ API ผ่าน TestRestTemplate
[gist id="4b03d0f7a64d4ce2989d791aa22b108d" file="2.java"]- Slicing Testing เป็นการทดสอบเฉพาะ layer ใน Spring Boot เท่านั้น ซึ่งเร็วมาก ๆ เพราะว่า load บาง layer เท่านั้น เช่น
- Controller layer จะทดสอบผ่าน WebMvcTest
- Repository layer จะทดสอบผ่าน library ที่ติดต่อกับ database เช่น Spring Data จะมีให้หมด ทั้ง JDBCTest และ JPATest เป็นต้น
ตัวอย่างของการใช้งาน WebMvcTest
[gist id="4b03d0f7a64d4ce2989d791aa22b108d" file="3.java"]เรื่องที่ 3 ทั้ง JUnit 5 และ Spring Boot Testing สามารถทำงานกับ Mockito ได้
แต่ว่าใช้งาน และ ทำงานแตกต่างกัน
- ใช้งาน @Mock และ @InjectMock ในโลกของ Unit testing หรือ Java เท่านั้น ปกติใช้ทดสอบ logic การทำงานใน service layer เพราะว่า ไม่ต้องการ start web server ใด ๆ
- ใช้งาน @MockBean สำหรับการจำลอง dependency ใน integration testing ของ Spring Boot ได้ทั้ง Spring Boot test และ WebMvcTest
เรื่องที่ 4 ในการทดสอบ JSON message สามารถใช้งาน JSONPath และ JSONAssert ได้
แต่ปกติผมชอบใช้ JSONMapper มาแปลงเป็น object ก่อน
[gist id="4b03d0f7a64d4ce2989d791aa22b108d" file="4.java"]โดยทั้งหมดนี้ได้มาทันทีเมื่อสร้าง project ขึ้นมา
ดังนั้นไม่มีเหตุผลใด ๆ ที่จะไม่เขียน test นะ !!