การติดตาม TDD นำไปสู่ ​​DI อย่างหลีกเลี่ยงไม่ได้ไหม?


14

ฉันเรียนรู้ที่จะพัฒนา Test Driven Development (TDD), Dependency Injection (DI) และ Inversion of Control (IoC) ทั้งหมดในเวลาเดียวกัน เมื่อฉันเขียนรหัสโดยใช้ TDD ฉันมักจะจบลงด้วยการใช้ DI ใน Constructor ของชั้นเรียน ฉันสงสัยว่านี่เป็นเพราะฉันเรียนรู้ที่จะทำ TDD หรือถ้านี่เป็นผลข้างเคียงตามธรรมชาติของ TDD

ดังนั้นคำถามของฉันคือ: ทำตามหลักการของ TDD และการทดสอบหน่วยการเขียนที่ไม่ได้ขึ้นอยู่กับบริการภายนอกที่นำไปสู่ ​​DI อย่างหลีกเลี่ยงไม่?


8
ฉันกำลังอ่านศิลปะการทดสอบหน่วยและดูเหมือนว่าจะนำไปสู่การพึ่งพาการฉีด (DI) อย่างแน่นอน
โปรแกรมเมอร์

2
แล้วภาษานี้เกี่ยวกับอะไร? DI / etc เป็นสิ่งจำเป็นใน Java แต่นั่นเป็นเพราะข้อ จำกัด ด้านภาษา - ภาษาอย่าง Python ไม่ต้องการเนื่องจากสามารถใช้การแก้ไขแพตช์ในการทดสอบ
Izkata

@Izkata: ฉันยอมรับว่า DI เป็นวิธีแก้ปัญหาสำหรับข้อ จำกัด ทางภาษา แต่การจับลิงไม่จำเป็นเหมือนกันในภาษาที่เข้มงวดน้อยกว่า ท่ามกลางวิธีอื่น ๆ ที่ฉันต้องการฟังก์ชั่นชั้นหนึ่งซึ่งช่วยให้คุณทำตามธรรมชาติสิ่ง DI ประมาณโดยวินัย
Javier

คำตอบ:


19

การติดตาม TDD และการเขียนการทดสอบหน่วยที่ไม่ได้ขึ้นอยู่กับฐานข้อมูลหรือบริการภายนอกจะนำไปสู่ ​​DI อย่างหลีกเลี่ยงไม่ได้หรือไม่?

สำหรับคำจำกัดความกว้างของ DI, ใช่ ชั้นเรียนไม่มีอยู่ในการฉีดวัคซีนดังนั้นพวกเขาจึงจำเป็นต้องเติมเต็มการอ้างอิงของพวกเขาอย่างใด บางครั้งแค่ให้คุณค่าก็ดี บางครั้งคุณต้องให้การเยาะเย้ยในตัวสร้าง บางครั้งผ่านคอนเทนเนอร์ IoC บางครั้งผ่าน accessor ทดสอบส่วนตัว มันคือทั้งหมดที่ฉีดสิ่งทดสอบเข้าไปในชั้นเรียนเพื่อให้สามารถทำงานแยกกันได้


9

สำหรับคนที่รู้เรื่อง DI อยู่แล้ว แต่ไม่เคยเห็นประเด็นนี้มาก่อนฉันคิดว่าการทดสอบหน่วยเกือบจะนำไปสู่การใช้ DI อย่างสม่ำเสมอ

หากคุณไม่ทราบเกี่ยวกับ DI และกำลังพยายามที่จะทดสอบหน่วยเขียนบางคนตามธรรมชาติจะบูรณาการ DI บางส่วนจะได้รับความผิดหวังและในที่สุดก็ค้นพบ DI ผ่านการวิจัย แต่คุณจะแปลกใจว่าบ่อยครั้งมันก็จะไม่เกิดขึ้นกับใครบางคน อาจมีวิธีที่ดีกว่าในการออกแบบซอฟต์แวร์เพื่อให้การทดสอบหน่วยง่ายขึ้น คนเหล่านั้นเขียนการทดสอบหน่วยเป็นดื้อดึงและยอมแพ้


8

การทดสอบหน่วยจะนำไปสู่ ​​DI (เนื่องจากเป็นการบังคับให้คุณสร้างหน่วยคู่ที่หลวม ๆ ) TDD ไม่จำเป็นเนื่องจาก TDD สามารถใช้ในการสร้างการทดสอบแบบทีละชั้นแทนที่จะใช้การทดสอบแบบ "คำต่อคำ" ดูบทความนี้

http://stephenwalther.com/archive/2009/04/11/tdd-tests-are-not-unit-tests.aspx

สำหรับคำอธิบายของความแตกต่าง


1
+1 สำหรับ "TDD ไม่ใช่ UT" นอกจากนี้สำหรับการรับรู้ว่าการแยกส่วนที่รุนแรงเป็นผลร่วมกันของ UT ไม่จำเป็นต้องมีของ TDD
Javier

3

ใช่และไม่ใช่: TDD นำไปสู่การเขียนโค้ดที่มีโครงสร้างที่ดีซึ่งนำไปสู่ ​​DI

โดยที่ฉันหมายถึง TDD โดยทั่วไปจะส่งวิธีที่ถูกต้องเกี่ยวกับการห่อหุ้ม SRP และการใช้ซ้ำได้ ไม่ใช่แค่การทดสอบรอบรหัสของคุณ: มันเกี่ยวกับการใช้การทดสอบเหล่านั้นเพื่อออกแบบให้ดีขึ้น หากวัตถุสร้างการขึ้นต่อกันของตัวเองวัตถุนั้นจะอาศัยอยู่ในบริบทที่เฉพาะเจาะจงภายในแอปพลิเคชันเฉพาะและมีแนวโน้มที่จะนำไปใช้ในแอปพลิเคชันในระดับที่สูงขึ้น DI เป็นสิ่งที่ดีไม่ใช่แค่จากมุมมองการทดสอบ แต่ยังมาจากมุมมองคุณภาพของโค้ดด้วย


คุณช่วยอธิบายส่วนที่ไม่ใช่ของใช่และไม่มีคำตอบของคุณ? วิธีการหนึ่งทำ TDD โดยไม่ต้อง DI
Gilles

ส่วน 'ไม่' เป็นฉันไม่คิดว่ามันเป็นการเชื่อมโยงโดยตรงระหว่าง TDD และ DI มันเป็นทางอ้อมผ่านคุณภาพของรหัส ซึ่งอาจมีการแบ่งผม แต่แค่คิดว่าฉันจะชี้ให้เห็นว่าคุณภาพของรหัสเป็นสิ่งที่คุณต้องการไม่ใช่แค่การทดสอบ
ทิม

0

ตามที่ระบุไว้แล้วในคำตอบอื่น ๆ TDD ไม่จำเป็นต้องมีการทดสอบหน่วย คุณสามารถเขียนการทดสอบบูรณาการ / การทำงานในขณะที่ทำ TDD จากหลายวิธีในการใช้ TDD การสร้างการทดสอบหน่วยจะเป็นแบบ "ปลอมจนกว่าคุณจะทำ" (ดูรายละเอียดจากหนังสือของ Kent Beck)

สำหรับ "TDD นำไปสู่ ​​DI อย่างหลีกเลี่ยงไม่ได้แน่นอน สิ่งที่ต้องการเมื่อเขียนการทดสอบหน่วยคือการแยกหน่วยที่กำลังทดสอบออกจากการใช้งานการอ้างอิงภายนอก และสิ่งนี้สามารถทำได้อย่างง่ายดายเพียงแค่มีหรือไม่มี DI วิธีที่ดีที่สุดคือการใช้เครื่องมือแยก / เยาะเย้ยที่เหมาะสม


แต่การใช้ mocks คุณไม่จำเป็นต้องฉีดการพึ่งพาในชั้นเรียนใช่มั้ย
Gilles
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.