3 คะแนน โดย GN⁺ 2025-12-30 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • ผู้ดูแลหลักของ 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 ความคิดเห็น

 
GN⁺ 2025-12-30
ความคิดเห็นบน 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 ผมก็ยังรู้สึกระแวง

    • ถ้าเป็น “dummy เวอร์ชันที่มีพฤติกรรมถูกต้องขั้นต่ำ” มันก็น่าจะตรงกับนิยามของ mock อยู่แล้วไม่ใช่หรือ
    • ถ้า dummy แบบนั้นไม่ได้ทำด้วย mock ก็แปลว่าคุณกำลังใช้ mock ผิดวิธี
    • ผมก็ได้ข้อสรุปคล้ายกันที่ Google ในกรณีส่วนใหญ่ fake ดีกว่า mock แต่ถ้าไม่ได้อยู่ในสภาพแวดล้อมแบบ Google ที่เข้าถึง source ได้ทั้งหมด บางครั้ง mock ก็ยังจำเป็น
    • ผมใช้ Mockito เฉพาะตอน refactor legacy code หรือทดสอบ external library ในสถานการณ์ที่เลี่ยงไม่ได้เท่านั้น มันไม่เคยเป็นตัวเลือกแรก
    • การใช้ mock เกินจำเป็นเกิดจากความเข้าใจผิดเรื่อง “test pyramid” พอไปเน้นแต่ unit test ก็เลยผลิต test ที่เปราะบางและมูลค่าต่ำ ออกมามากมาย และตอนนี้ AI ก็กำลังทำให้สถานการณ์แย่ลงด้วยการสร้าง test แบบนี้อัตโนมัติ
  • ผมใช้ Mockito กับ Kotlin มา 4 ปี และใน 99% ของกรณีก็ใช้งานได้ดีพอ
    สถานการณ์ที่ซับซ้อนหรือชวนสับสนส่วนใหญ่มาจากการ แยก concerns ได้ไม่ดีพอ ของผมเอง
    ความต่างกับ MockK แทบไม่มี นอกจากเรื่อง syntax แต่ถ้า Mockito เลิกดูแลรักษา ก็คงต้องเริ่มคิดเรื่องย้าย

    • พอเห็นการถกเถียงแบบนี้กลับรู้สึกว่าเป็นหลักฐานว่าโปรเจ็กต์ประสบความสำเร็จมากกว่า ขอ ชนแก้วขอบคุณ ให้นักพัฒนาที่ทุ่มเทมานานกว่า 10 ปี
    • ดูไม่ใช่ความโกรธ แต่เป็นกระแสธรรมชาติแบบเดียวกับการย้ายไป Kotlin และ Rust มากกว่า
    • ผมคิดว่าควรปฏิเสธการรองรับ Kotlin ตั้งแต่แรก ถ้ามี framework เฉพาะสำหรับ Kotlin ไปเลยน่าจะดีกว่า
    • ปัญหาไม่ได้อยู่ที่ตัวเครื่องมือ แต่เป็นเพราะ mock กับ spy ใช้ง่ายเกินไป จนทำให้ ไม่ออกแบบโครงสร้างการทดสอบให้ดีพอ
  • mock มีประสิทธิภาพที่สุดเมื่อแอปพลิเคชันมี 4-5 ชั้น
    เมื่อก่อนผมก็ใช้ DI มากเกินไปจนสร้าง ใยแมงมุมของโค้ดที่ซับซ้อน แต่ตอนนี้ผมจำกัดจำนวนชั้นและรักษาโครงสร้างให้สม่ำเสมอ
    ผมใช้ mock สำหรับการทดสอบคลาสเดี่ยว และใช้ integration test สำหรับยืนยันความต้องการ
    สุดท้ายแล้วสิ่งสำคัญไม่ใช่เครื่องมือ แต่คือ วินัยของนักพัฒนา

  • Mockito คือ mocking framework ที่ได้รับความนิยมมากที่สุดใน Java

    • แต่พอได้เจอกับนรกแห่งการทดสอบที่สร้างจากมัน ก็รู้สึกเหมือน อายุสั้นลงไปเลย
    • ในภาษาสเปนมันแปลว่า “ขี้มูกก้อนเล็ก” ชื่อนี้เลยดูขำๆ
  • เพราะการเปลี่ยนแปลงของแพลตฟอร์ม Mockito เลยเปลี่ยนมาเป็นแบบ agent-based เนื่องจากตั้งแต่ JVM 22 เป็นต้นไป การโหลด dynamic agent ถูกซ่อนไว้หลังแฟล็ก
    การเปลี่ยนแปลงแบบนี้อาจทำให้การนำไปใช้ในองค์กรช้าลงได้

    • มันก็แค่ต้องเพิ่มแฟล็กระหว่างรันเทสต์เท่านั้น
    • ยังไงบริษัทส่วนใหญ่ก็กำลังย้ายจาก Java 8 ไป 17 กันอยู่ ดังนั้น JVM 22 ยังเป็นเรื่องไกลตัวอีกมาก
  • การเปลี่ยนแปลงของแพลตฟอร์มทำให้รู้สึกเหมือนชุมชน Mockito ถูก ผลักภาระเกินควร
    การกล่าวหาทำนองว่า “กำลังขัดขวาง ecosystem ของ JVM” ผมว่าไม่ค่อยดีต่อสุขภาพเท่าไร

    • แต่ทีม JDK ก็ประกาศเรื่องการเปลี่ยนแปลงนี้มาหลายปีแล้ว แค่เพิ่มการตั้งค่าเล็กน้อยก็ยังใช้ความสามารถแบบ dynamic ได้อยู่ และนี่เป็นทางเลือกที่ถูกต้องเพื่อ การเพิ่มประสิทธิภาพของแพลตฟอร์มและความปลอดภัย
  • การดูแลโอเพนซอร์สดูเป็นงานที่ บั่นทอนพลังมาก จริงๆ
    ถ้าเป็นผมคง archive แล้วถอยออกมานานแล้ว หวังว่า Tim จะได้พบความสงบเสียที

    • ถึงอย่างนั้นผมก็คิดว่านี่เป็นการ ลงจากตำแหน่งอย่างสง่างาม ผมเคารพความพยายามที่ทุ่มเทมายาวนาน และสิ่งที่ Tim ทำสำเร็จจะเป็นเรื่องน่าภูมิใจตลอดไป
  • อยากกล่าวคำขอบคุณถึง TimvdLippe เขาแสดงให้เห็นทั้งวิสัยทัศน์และความทุ่มเทที่ยอดเยี่ยม

  • Mockito ถ้าอยู่ในมือของคนที่เข้าใจการทดสอบดีก็ใช้งานได้ไม่มีปัญหา
    ไม่ว่าในภาษาไหนหรือ framework อะไรก็ตาม test ที่แย่เป็นความผิดของคนเขียน

  • “Agent” หมายถึงเครื่องมือที่แนบเข้ากับ JVM แล้วสามารถ instrument/แก้ไข แอปพลิเคชันที่กำลังรันอยู่ได้
    profiler, debugger, monitoring tool ต่างก็ใช้กลไกนี้
    ตั้งแต่ Java 21 เป็นต้นมา ฟังก์ชันนี้ถูกปิดไว้เป็นค่าเริ่มต้นเพื่อเพิ่มความปลอดภัย และจะอนุญาตได้ผ่านแฟล็ก -XX:+EnableDynamicAgentLoading เท่านั้น
    รายละเอียดเพิ่มเติมดูได้ที่ เอกสาร JEP 451

    • ในเอกสารเดียวกัน JEP 451: Prepare to Disallow the Dynamic Loading of Agents มีคำอธิบายเบื้องหลังไว้ด้วย
    • เมื่อก่อนสามารถต่อ debugger เข้าผ่านพอร์ตระหว่าง runtime ได้ แต่ตอนนี้เพราะปัญหาด้านความปลอดภัย จึงต้อง ลงทะเบียน agent อย่างชัดเจนตั้งแต่ตอนเริ่มต้น