- ผู้ดูแลหลักของ Mockito เปิดเผยว่า ณ เดือนมีนาคม 2026 จะเป็นการ สิ้นสุดบทบาทการดูแลรักษาตลอดราว 10 ปี และมีแผนจะ ค่อย ๆ ถ่ายโอนอำนาจหน้าที่ ในช่วงหลายเดือนข้างหน้า
- เขาระบุว่าหนึ่งในชนวนโดยตรงของการตัดสินใจคือ การเปลี่ยนนโยบายเอเจนต์ใน JVM 22 โดยแม้จะเห็นด้วยกับการเปลี่ยนแปลงเพื่อความปลอดภัย แต่ก็รู้สึกว่า การบังคับให้เปลี่ยนแบบฝ่ายเดียวโดยไม่มีทางเลือกอื่นและขาดการคำนึงถึงระบบนิเวศโดยรวม กลายเป็นภาระหนัก
- โดยเฉพาะอย่างยิ่ง แม้ว่า Mockito จะเป็นหนึ่งในผู้ใช้งาน JVM agent รายใหญ่ที่สุด แต่กลับต้องแบกรับการแก้ปัญหาเอง โดยไม่มีทั้งการสนับสนุนจากเครื่องมือ build หรือการหารือแบบร่วมมือกัน ซึ่งนำไปสู่ ความเหนื่อยล้าจากการใช้ทรัพยากรและภาระความรับผิดชอบที่มากเกินไป
- อีกปัจจัยหนึ่งที่ถูกชี้ถึงคือ ความซับซ้อนเชิงโครงสร้างของการรองรับ Kotlin โดยฟีเจอร์ที่ไม่สอดคล้องกับลักษณะการทำงานเฉพาะของ JVM ใน Kotlin ทำให้ภายใน Mockito มี API ซ้ำซ้อนและตรรกะแยกสาขาเพิ่มขึ้น จนดูแลรักษาได้ยาก
- ช่วงหลังเขารู้สึกสนุกและมีแรงจูงใจมากกว่ากับการทำงานบน Servo เว็บเอนจินที่พัฒนาด้วย Rust และเมื่อพิจารณาจากเวลาส่วนตัวที่มีจำกัด จึงสรุปได้ว่า ยากจะทำงานดูแลรักษาแบบอาสาสมัครที่ให้ความรู้สึกเหมือนเป็นภาระหน้าที่ต่อไป
หลักไมล์ 10 ปีและการตัดสินใจถ่ายโอนบทบาท
- เดือนมีนาคม 2026 จะเป็นวาระครบรอบ 10 ปีของการดูแล Mockito และเขามองว่าจุดนั้นเป็น จังหวะธรรมชาติสำหรับการส่งต่อความรับผิดชอบ
- ในช่วงหลายเดือนข้างหน้า เขามีแผนจะโฟกัสที่ การถ่ายทอดความรู้และทำให้การเปลี่ยนผ่านมีเสถียรภาพ ในฐานะผู้ดูแลคนปัจจุบัน
- การหารือเรื่องโครงสร้างผู้ดูแลชุดถัดไปและโรดแมประยะยาวจะ ดำเนินต่อใน GitHub issue แยกต่างหาก
ความเหนื่อยล้าจากการเปลี่ยนนโยบาย JVM agent
- ฉากหลังที่ทำให้ อาร์ติแฟกต์หลักใน Mockito 5 เปลี่ยนมาใช้ JVM agent คือการเปลี่ยนนโยบายตั้งแต่ JVM 22 ที่ซ่อนการแนบ dynamic agent ไว้หลังแฟล็ก
- แม้จะเห็นด้วยกับเจตนาของการเปลี่ยนแปลงในมุมความปลอดภัย แต่ก็ชี้ว่าปัญหาคือ การทำให้การตัดสินใจกลายเป็นข้อเท็จจริงที่ต้องยอมรับ โดยไม่มีทั้งการออกแบบทางเลือกหรือการสนับสนุนการย้ายระบบ
- แม้ที่ผ่านมา Mockito มักถูกใช้เป็นกรณีนำร่องของความสามารถใหม่ใน JVM แต่ในการเปลี่ยนแปลงครั้งนี้ วงจร feedback แบบร่วมมือกันกลับไม่ทำงาน
- เขาประเมินว่า ความจริงที่การสนับสนุนระดับเครื่องมือ build สำหรับ agent ยังมีไม่เพียงพอ สะท้อนว่าฟีเจอร์นี้ยังมีลำดับความสำคัญต่ำ
- เขาเน้นว่า หากกดดันผู้ดูแลที่เป็นผู้มีส่วนร่วมโดยสมัครใจมากเกินไป โครงสร้างความร่วมมือแบบโอเพนซอร์สย่อมพังลงได้ง่าย
ภาระเชิงโครงสร้างที่เกิดจากการรองรับ Kotlin
- เขาไม่ได้ปฏิเสธการแพร่หลายของ Kotlin แต่ชี้ว่าเพราะ ความแตกต่างของวิธีทำงานภายใน JVM ทำให้ใน
mockito-core ต้องเพิ่ม เส้นทางประมวลผลเฉพาะสำหรับ Kotlin จำนวนมาก
- ฟีเจอร์ของ Kotlin อย่าง suspend function มีกรณีที่ ทำงานได้ไม่สม่ำเสมอ ส่งผลให้ API ซ้ำซ้อนและความซับซ้อนเพิ่มขึ้น
- ผลลัพธ์คือ codebase กลายเป็นสปาเกตตีและดูแลรักษายากขึ้น และเขาก็พูดอย่างตรงไปตรงมาว่างานลักษณะนี้ไม่ได้สร้างความสนุกให้กับตน
- อนาคตที่เอนเอียงไปทาง Kotlin มากขึ้น กลายเป็นปัจจัยที่บั่นทอนแรงจูงใจในการดูแล Mockito ระยะยาว
การได้ความสนุกกลับคืนจากกิจกรรมโอเพนซอร์สอื่น
- เขามีส่วนร่วมกับโปรเจกต์โอเพนซอร์สมาหลายโครงการ และช่วงหลังได้กลับมารู้สึกสนุกกับการพัฒนาผ่านงานบน Servo เว็บเอนจินที่พัฒนาด้วย Rust
- ท่ามกลางตัวเลือกของเวลาช่วงเย็นที่มีจำกัด โปรเจกต์อื่น ให้ความพึงพอใจมากกว่า Mockito อย่างต่อเนื่อง
- เขามองว่าสถานะที่งานดูแลรักษาแบบอาสาสมัคร ถูกทำต่อไปในสภาพที่รู้สึกเหมือนเป็นหน้าที่ระยะยาวนั้นไม่ใช่เรื่องพึงประสงค์
ภาพรวมของเหตุผลและสารที่ต้องการสื่อ
- ความท้อแท้จากการเปลี่ยนนโยบาย JVM ข้อจำกัดเชิงโครงสร้างของการรองรับ Kotlin และการได้แรงจูงใจกลับคืนจากโปรเจกต์อื่น เป็น ปัจจัยหลักของการตัดสินใจครั้งนี้
- เขายอมรับว่าปัจจัยเหล่านี้ไม่ได้ใช้กับผู้มีส่วนร่วมทุกคนเหมือนกัน และ บางคนอาจพร้อมผลักดันการรองรับ Kotlin มากกว่า
- เขาตัดสินใจวางมือจากบทบาทนี้ด้วยมุมมองว่า การเปลี่ยนผู้ดูแลจะเป็นผลดีต่อสุขภาพระยะยาวของโปรเจกต์มากกว่า
- เขาประเมินว่าประสบการณ์การดูแลโอเพนซอร์สครั้งนี้ เป็นทั้งเกียรติและสิทธิพิเศษ และยังแนะนำให้ผู้อื่นเข้ามามีส่วนร่วมแบบอาสาสมัครด้วย
1 ความคิดเห็น
ความคิดเห็นบน Hacker News
ตอนทำโปรเจ็กต์ที่สองที่ Google ผมเลิกใช้ mocking ไปเลย
ตอนรีไรต์ระบบด้วย GWT มีการบังคับให้ทำ test coverage แต่ทุกคนทดสอบแค่ service ของตัวเองและ inject mock ผ่าน DI
ผลคือระบบ เปราะบางอย่างมาก และ service ที่มีอายุแค่ 8 สัปดาห์ก็ให้ความรู้สึกเหมือน legacy code แค่เปลี่ยนลำดับฝั่ง backend หรือจำนวนครั้งของการเรียกใช้ ก็ต้องเสียเวลาทั้งวันไปกับการแก้ mock
โครงสร้าง Guice module ก็ซับซ้อนมาก จนถ้าจะ inject mock สำหรับสภาพแวดล้อมทดสอบก็ต้องสร้าง injector คนละชุดไปเลย สุดท้าย test กับ production กลายเป็นคนละสภาพแวดล้อม
แถมยังเสียทรัพยากรวิศวกรรมไปมากกับการถกเถียง EasyMock vs Mockito
หลังจากนั้นผมแทบไม่ใช้ mock อีกเลย ผมคิดว่าการสร้าง dummy service แบบง่ายๆ ที่เลียนแบบพฤติกรรมจริงเท่าที่จำเป็นดีกว่ามาก
จนถึงตอนนี้พอเห็นคนยึดติดกับ mock ผมก็ยังรู้สึกระแวง
ผมใช้ Mockito กับ Kotlin มา 4 ปี และใน 99% ของกรณีก็ใช้งานได้ดีพอ
สถานการณ์ที่ซับซ้อนหรือชวนสับสนส่วนใหญ่มาจากการ แยก concerns ได้ไม่ดีพอ ของผมเอง
ความต่างกับ MockK แทบไม่มี นอกจากเรื่อง syntax แต่ถ้า Mockito เลิกดูแลรักษา ก็คงต้องเริ่มคิดเรื่องย้าย
mock มีประสิทธิภาพที่สุดเมื่อแอปพลิเคชันมี 4-5 ชั้น
เมื่อก่อนผมก็ใช้ DI มากเกินไปจนสร้าง ใยแมงมุมของโค้ดที่ซับซ้อน แต่ตอนนี้ผมจำกัดจำนวนชั้นและรักษาโครงสร้างให้สม่ำเสมอ
ผมใช้ mock สำหรับการทดสอบคลาสเดี่ยว และใช้ integration test สำหรับยืนยันความต้องการ
สุดท้ายแล้วสิ่งสำคัญไม่ใช่เครื่องมือ แต่คือ วินัยของนักพัฒนา
Mockito คือ mocking framework ที่ได้รับความนิยมมากที่สุดใน Java
เพราะการเปลี่ยนแปลงของแพลตฟอร์ม Mockito เลยเปลี่ยนมาเป็นแบบ agent-based เนื่องจากตั้งแต่ JVM 22 เป็นต้นไป การโหลด dynamic agent ถูกซ่อนไว้หลังแฟล็ก
การเปลี่ยนแปลงแบบนี้อาจทำให้การนำไปใช้ในองค์กรช้าลงได้
การเปลี่ยนแปลงของแพลตฟอร์มทำให้รู้สึกเหมือนชุมชน Mockito ถูก ผลักภาระเกินควร
การกล่าวหาทำนองว่า “กำลังขัดขวาง ecosystem ของ JVM” ผมว่าไม่ค่อยดีต่อสุขภาพเท่าไร
การดูแลโอเพนซอร์สดูเป็นงานที่ บั่นทอนพลังมาก จริงๆ
ถ้าเป็นผมคง archive แล้วถอยออกมานานแล้ว หวังว่า Tim จะได้พบความสงบเสียที
อยากกล่าวคำขอบคุณถึง TimvdLippe เขาแสดงให้เห็นทั้งวิสัยทัศน์และความทุ่มเทที่ยอดเยี่ยม
Mockito ถ้าอยู่ในมือของคนที่เข้าใจการทดสอบดีก็ใช้งานได้ไม่มีปัญหา
ไม่ว่าในภาษาไหนหรือ framework อะไรก็ตาม test ที่แย่เป็นความผิดของคนเขียน
“Agent” หมายถึงเครื่องมือที่แนบเข้ากับ JVM แล้วสามารถ instrument/แก้ไข แอปพลิเคชันที่กำลังรันอยู่ได้
profiler, debugger, monitoring tool ต่างก็ใช้กลไกนี้
ตั้งแต่ Java 21 เป็นต้นมา ฟังก์ชันนี้ถูกปิดไว้เป็นค่าเริ่มต้นเพื่อเพิ่มความปลอดภัย และจะอนุญาตได้ผ่านแฟล็ก
-XX:+EnableDynamicAgentLoadingเท่านั้นรายละเอียดเพิ่มเติมดูได้ที่ เอกสาร JEP 451