ฉันมีชั้นเรียนซึ่งได้รับการปรับโครงสร้างใหม่ใน 1 ชั้นหลักและชั้นเรียนขนาดเล็ก 2 ชั้น คลาสหลักใช้ฐานข้อมูล (เหมือนคลาสของฉัน) และส่งอีเมล ดังนั้นคลาสหลักจะมีIPersonRepository
และแบบIEmailRepository
ที่เขาส่งไปยังคลาสที่เล็กกว่า 2 คลาส
ตอนนี้ฉันต้องการทดสอบหน่วยหลักและเรียนรู้ที่จะไม่คัดลอกงานภายในของชั้นเรียนเพราะเราควรจะสามารถเปลี่ยนงานภายในโดยไม่ต้องทำการทดสอบหน่วย
แต่เป็นชั้นใช้IPersonRepository
และIEmailRepository
ผมมีการระบุ (จำลอง / จำลอง) IPersonRepository
ผลการค้นหาสำหรับวิธีการบางอย่างสำหรับ คลาสหลักจะคำนวณข้อมูลบางส่วนตามข้อมูลที่มีอยู่และส่งคืนข้อมูลนั้น ถ้าฉันต้องการทดสอบสิ่งนั้นฉันไม่เห็นว่าฉันจะเขียนแบบทดสอบได้อย่างไรโดยไม่ระบุว่าIPersonRepository.GetSavingsByCustomerId
ผลตอบแทน x แต่จากนั้นการทดสอบหน่วยของฉัน 'รู้' เกี่ยวกับงานภายในเพราะ 'รู้' ว่าวิธีไหนที่จะเยาะเย้ยและไม่ทำ
ฉันจะทดสอบคลาสที่ฉีดการพึ่งพาโดยไม่ต้องทดสอบรู้เกี่ยวกับ internals ได้อย่างไร
พื้นหลัง:
จากประสบการณ์ของฉันการทดสอบจำนวนมากเช่นนี้สร้าง mocks สำหรับที่เก็บข้อมูลจากนั้นให้ข้อมูลที่ถูกต้องสำหรับ mocks หรือทดสอบว่ามีการเรียกเมธอดเฉพาะระหว่างการดำเนินการหรือไม่ ทั้งสองวิธีการทดสอบรู้เกี่ยวกับ internals
ตอนนี้ฉันได้เห็นการนำเสนอเกี่ยวกับทฤษฎี (ซึ่งฉันเคยได้ยินมาก่อน) ว่าการทดสอบไม่ควรรู้เกี่ยวกับการนำไปใช้ ก่อนอื่นเพราะคุณไม่ได้ทดสอบวิธีการทำงาน แต่ยังเพราะเมื่อคุณเปลี่ยนการใช้งานการทดสอบหน่วยทั้งหมดล้มเหลวเพราะพวกเขา 'รู้' เกี่ยวกับการใช้งาน ในขณะที่ฉันชอบแนวคิดของการทดสอบที่ไม่รู้ว่าจะนำไปใช้อย่างไรฉันก็ไม่รู้ว่าจะทำอย่างไร
IPersonRepository
วัตถุอินเตอร์เฟสนั้นและวิธีการทั้งหมดที่อธิบายไม่ได้เป็น "ภายใน" อีกต่อไปดังนั้นมันจึงไม่ใช่ปัญหาของการทดสอบ คำถามจริงของคุณควรเป็น "ฉันจะปรับโครงสร้างชั้นเรียนเป็นหน่วยย่อยโดยไม่เปิดเผยต่อสาธารณะมากเกินไป" ได้อย่างไร คำตอบคือ "รักษาอินเทอร์เฟซเหล่านั้นแบบลีน" (โดยยึดหลักการการแยกอินเทอร์เฟซตัวอย่าง) นั่นคือ IMHO จุดที่ 2 ในคำตอบของ @ DavidArno (ฉันเดาว่าไม่จำเป็นที่ฉันจะต้องทำซ้ำในคำตอบอื่น)