เมื่อถึงจุดหนึ่งในอาชีพ Rails ของคุณ คุณจะได้พบกับคอนโทรลเลอร์ที่จะทำให้คุณเลิกเขียนโปรแกรมไปตลอดกาล อาจมีโค้ดทุกบรรทัดสำหรับคุณลักษณะทั้งหมด อาจมี 15 before_filters
ที่ทุกคนสื่อสารผ่านตัวแปรอินสแตนซ์และต้องถูกเรียกในลำดับเฉพาะหรือสิ่งต่าง ๆ ที่ระเบิดขึ้น และการทดสอบของมันก็จะมีลักษณะดังนี้:
test "index" do
get :index
assert_response :success
end
สุดยอด. ครอบคลุมการทดสอบ 100% ใช่ไหม
ดีที่สุดเท่าที่จะเป็นได้เพียงแค่หลับตาและแสร้งทำเป็นว่าไม่มีอยู่จริงสักวันหนึ่งคุณจะต้องแก้ไขข้อผิดพลาดในตัวควบคุมเหล่านี้ และในฐานะนักพัฒนาซอฟต์แวร์ที่ดี คุณต้องปล่อยให้โค้ดดีกว่าที่คุณพบ
แต่คุณจะปรับโครงสร้างใหม่ได้อย่างไร โดยเฉพาะอย่างยิ่งหากไม่มีการทดสอบที่ดีที่ต้องพึ่งพา
ทดสอบได้เลย (อย่างใด)
คุณต้องการการทดสอบที่ดีเพื่อให้รู้สึกปลอดภัยขณะจัดโครงสร้างใหม่ แต่คุณไม่สามารถเขียน การทดสอบที่ดีกับรหัสนี้ จนถึง คุณปรับโครงสร้างใหม่ แล้วคุณทำอะไรได้บ้าง?
ไม่ว่าคุณจะเขียนคอนโทรลเลอร์ของคุณแย่แค่ไหน คุณยังสามารถเขียนการทดสอบการรวมที่ส่งข้อมูลบางส่วนไปยังคอนโทรลเลอร์และคาดหวังการตอบสนองจากมัน สำหรับตอนนี้ คุณควรเขียนการทดสอบเพื่อให้แน่ใจว่าตัวควบคุม มีอยู่ พฤติกรรมไม่เปลี่ยน ในขณะที่คุณปรับโครงสร้างใหม่
การทดสอบเหล่านี้จะไม่เน้นเหมือนการทดสอบหน่วย แต่การทดสอบระดับสูงเหล่านี้สามารถทำให้คุณรู้สึกสบายใจว่าการปรับโครงสร้างใหม่ที่คุณกำลังจะทำจะไม่ทำลายทุกสิ่งทุกอย่าง และขั้นตอนในการเขียนจะช่วยให้คุณเข้าใจโค้ดของคุณได้ดีขึ้น ซึ่งจะช่วยให้คุณตัดสินใจว่าจะปรับโครงสร้างใหม่อย่างไร
ทำลายการพึ่งพาของคุณ
อะไรทำให้โค้ดคอนโทรลเลอร์เสียแย่? โดยส่วนใหญ่ มันคือการพึ่งพาโดยนัย ระหว่าง before_filters
, วิธีตัวช่วย หรือส่วนต่างๆ ของฟังก์ชัน 200 บรรทัด นอกจากนี้ยังอาจเป็นกรณีของการปรับโครงสร้างใหม่เร็วเกินไป ในการทำให้โค้ดดีขึ้น คุณต้องทำลายการขึ้นต่อกันเหล่านี้
สำหรับตัวควบคุม Rails มีวิธีง่ายๆ ในการทำลายการพึ่งพา เพียงคัดลอกโค้ดจาก before_filters
. ของคุณ , เมธอดตัวช่วย, ซูเปอร์คลาส, และที่อื่น ๆ โค้ดคอนโทรลเลอร์-ish อาจถูกซ่อนไว้ จากนั้นให้แทนที่การเรียกไปยังวิธีการเหล่านั้นด้วยรหัสที่คุณคัดลอก
คุณกำลังยกเลิกการทำให้โค้ดของคุณแห้งชั่วคราว ดังนั้นคุณจึงสามารถจัดโครงสร้างใหม่ในลักษณะที่เข้าใจได้ง่ายขึ้นในภายหลัง มันน่าเกลียด แต่ตอนนี้รหัสทั้งหมดของคุณถูกเปิดเผย คุณควรจะสามารถเห็นได้ว่าชิ้นส่วนใดโต้ตอบกันและทุกอย่างดำเนินไปอย่างไร
(ในระหว่างขั้นตอนนี้ คุณควรทำการทดสอบหลังจากการเปลี่ยนแปลงทุกครั้งเพื่อให้แน่ใจว่าอินไลน์ของคุณจะไม่ทำลายสิ่งใดๆ)
รีแฟคเตอร์ไปยังโค้ดที่ทดสอบได้
ตอนนี้ คุณพร้อมที่จะจัดโครงสร้างโค้ดของคุณใหม่แล้ว คุณอาจจะยึดติดกับวิธีการสกัดพื้นฐาน , แยกวัตถุ , วิธีดึงขึ้น -ประเภทการปรับโครงสร้างใหม่ ลองจัดโครงสร้างโค้ดใหม่ด้วยวิธีต่างๆ กันและดูว่าแบบไหนดีที่สุด
ในช่วงสองสามรอบแรก คุณสามารถไว้วางใจการทดสอบการรวมระดับสูงของคุณในฐานะเครือข่ายความปลอดภัย แต่ในไม่ช้าคุณจะต้องการสิ่งที่ดีกว่า
ในขณะที่คุณปรับโครงสร้างใหม่ ให้มองหาโอกาสที่จะทำให้โค้ดของคุณสามารถทดสอบได้มากขึ้น ซึ่งมักจะหมายถึงการสร้างสถานที่เพื่อฉีดการทดสอบเป็นสองเท่า ลดการพึ่งพาระหว่างอ็อบเจ็กต์ของคุณ และทำให้คอนโทรลเลอร์ของคุณพึ่งพาอ็อบเจ็กต์ที่สามารถสร้างและทดสอบหน่วยได้อย่างง่ายดาย การย้ายโค้ดไปยังวัตถุที่ทดสอบได้จะทำให้ตัวควบคุมมีขนาดเล็กลง เข้าใจง่ายขึ้น และทดสอบตัวเองได้ง่ายขึ้น
ฉันขอเป็นรายการลำดับเลขได้ไหม
อีกครั้ง นี่คือขั้นตอนที่ต้องทำเพื่อแยกตัวควบคุมขนาดใหญ่:
- รับการทดสอบการรวมระดับสูงกับคอนโทรลเลอร์
- ทำการทดสอบ ตรวจสอบให้แน่ใจว่าผ่าน
- อินไลน์
before_filters
, เมธอด superclass และ abstractions อื่นๆ ที่ซ่อนโค้ด - ทำการทดสอบ ตรวจสอบให้แน่ใจว่ายังผ่าน
- ทำการ refactoring (extract method , แยกวัตถุบริการ , แทนที่ตัวแปรอินสแตนซ์ด้วยโลคัล เป็นต้น) ดูว่ารหัสรู้สึกดีขึ้นหรือไม่
- ทำการทดสอบ ตรวจสอบให้แน่ใจว่ายังผ่าน
- หากคุณเพิ่งแตกโค้ด ให้เขียนการทดสอบหน่วยเทียบกับอ็อบเจ็กต์หรือเมธอดที่คุณแตกออกมา
- ทำการทดสอบ ตรวจสอบให้แน่ใจว่ายังผ่าน
- หากคอนโทรลเลอร์ยังคงต้องทำงาน ให้กลับไปที่ขั้นตอนที่ 5
มีอะไรต่อไป
หากคุณต้องการเรียนรู้เพิ่มเติม การทำงานอย่างมีประสิทธิภาพด้วยรหัสเดิมคือพระคัมภีร์ของการจดรหัสที่ไม่สามารถบำรุงรักษาได้โดยไม่มีการทดสอบใดๆ และเปลี่ยนเป็นสิ่งที่คุณสามารถทำงานด้วยได้ ฉันขอแนะนำอย่างยิ่ง หากคุณพบว่าตัวเองต้องเผชิญกับตัวควบคุมแบบเสาหินขนาดใหญ่บ่อยครั้ง (และหากการปรับโครงสร้างใหม่ทำให้คุณสนุกพอๆ กับที่ฉันทำ)
ตอนนี้ มาฟังเรื่องราวสยองขวัญของคุณกัน! โค้ดคอนโทรลเลอร์ที่แย่ที่สุดที่คุณเคยใช้มามีหน้าตาเป็นอย่างไร