วิธีการ ปรับปรุง DateTime.Now
ในการทดสอบ C#: คู่มืออย่างละเอียด
เมื่อพัฒนาแอปพลิเคชัน C# การพึ่งพาเวลาและวันที่ปัจจุบันในการคำนวณต่างๆ เป็นสิ่งที่พบได้ทั่วไป อย่างไรก็ตาม การพึ่งพานี้สามารถสร้างความท้าทายที่สำคัญเมื่อพูดถึงการทดสอบหน่วย หากโค้ดของคุณใช้ DateTime.Now
การทำการทดสอบซ้ำเพื่อยืนยันผลลัพธ์ตามวันที่ปัจจุบันอาจดูไม่สะดวกและอาจนำไปสู่ผลลัพธ์ที่ไม่สอดคล้องกัน ดังนั้นจะทำอย่างไรเพื่อให้สามารถเขียนทับ DateTime.Now
ได้อย่างมีประสิทธิภาพเพื่อให้แน่ใจว่าการทดสอบนั้นเชื่อถือได้และคาดเดาได้?
ในบล็อกโพสต์นี้ เราจะสำรวจกลยุทธ์ที่มีประสิทธิภาพในการจัดการเวลาในการทดสอบหน่วยของคุณโดยการใช้อินเทอร์เฟซและการฉีดพึ่งพา
ความท้าทายในการใช้ DateTime.Now ในการทดสอบ
การใช้ DateTime.Now
ในสถานการณ์การทดสอบมีปัญหาหลายประการ:
- ผลลัพธ์ที่ไม่สอดคล้องกัน: การรันการทดสอบแต่ละครั้งอาจสร้างผลลัพธ์ที่แตกต่างกันหากพึ่งพาวันที่และเวลาปัจจุบัน
- การทดสอบเคสขอบที่ยาก: คุณอาจต้องการทดสอบสถานการณ์ที่เกิดขึ้นในช่วงเวลาที่เฉพาะเจาะจง เช่น รอบเที่ยงคืนหรือในวันธรรมดาบางวัน การใช้
DateTime.Now
ทำให้เรื่องนี้ท้าทายและอาจป้องกันไม่ให้คุณสามารถจำลองข้อบกพร่องได้อย่างมีประสิทธิภาพ
เพื่อแก้ไขปัญหาเหล่านี้ พิจารณาการคิดมุมมองที่มีการควบคุมมากขึ้นในการจัดการเวลาในทดสอบของคุณ
แนวทางที่มีโครงสร้าง: อินเทอร์เฟซ IClock
ขั้นตอนที่ 1: กำหนดอินเทอร์เฟซ IClock
เพื่อแยกตรรกะของแอปพลิเคชันของคุณจากการพึ่งพาเวลาจริง ให้สร้างอินเทอร์เฟซชื่อว่า IClock
อินเทอร์เฟซนี้จะให้คุณสมบัติที่ส่งคืน DateTime ปัจจุบัน:
interface IClock
{
DateTime Now { get; }
}
ขั้นตอนที่ 2: นำเสนอ SystemClock
ถัดไป สร้างการนำเสนอที่เป็นรูปธรรมของอินเทอร์เฟซนี้ ซึ่งเรียกเวลาจริง:
class SystemClock : IClock
{
public DateTime Now { get { return DateTime.Now; } }
}
ขั้นตอนที่ 3: สร้าง StaticClock สำหรับการทดสอบ
ตอนนี้ กำหนดนาฬิกาที่สามารถส่งคืนเวลาแบบคงที่เพื่อใช้ในการทดสอบ:
class StaticClock : IClock
{
public DateTime Now { get { return new DateTime(2008, 09, 3, 9, 6, 13); } }
}
การใช้ StaticClock
จะช่วยให้คุณสามารถทำการทดสอบที่ขึ้นอยู่กับเวลาที่คุณควบคุมและคาดการณ์ได้
การฉีดพึ่งพา: ตัวกระตุ้นความยืดหยุ่น
เพื่อให้แน่ใจว่าคลาสของคุณได้รับการนำเสนอของนาฬิกาที่พวกเขาต้องการ ให้ใช้การฉีดพึ่งพา (DI) นี่คือวิธีการที่คุณสามารถทำได้:
- การฉีดผ่านคอนสตรัคเตอร์: ส่งคืนอินสแตนซ์ของ
IClock
เข้าสู่คอนสตรัคเตอร์ของคลาส - การฉีดด้วย Setter: จัดเตรียมเมธอด setter สำหรับกำหนดค่าอินสแตนซ์ของ
IClock
ที่เหมาะสม - คอนเทนเนอร์การควบคุมการย้อนกลับ: ใช้คอนเทนเนอร์ DI ในการจัดการวงจรชีวิตของการพึ่งพาของคุณอย่างมีประสิทธิภาพ
ตัวอย่างการนำเสนอ
นี่คือตัวอย่างคลาสที่พึ่งพา IClock
:
class YourClass
{
private readonly IClock _clock;
public YourClass(IClock clock)
{
_clock = clock;
}
public void YourMethod()
{
DateTime currentTime = _clock.Now;
// ตรรกะที่ขึ้นอยู่กับเวลาในปัจจุบัน
}
}
สรุป
ด้วยการแยกเวลาออกด้วยอินเทอร์เฟซและการนำเสนอนาฬิกาที่แตกต่างกัน คุณจะมั่นใจได้ว่าการทดสอบหน่วยของคุณสามารถคาดการณ์ได้ ทำซ้ำได้ และจัดการได้ง่าย หลีกเลี่ยงการใช้ DateTime.Now
โดยตรงในตรรกะของแอปพลิเคชันของคุณและเพลิดเพลินไปกับความยืดหยุ่นที่การออกแบบนี้เสนอในขณะที่คุณเผชิญกับสถานการณ์การทดสอบที่ไม่เหมือนใคร
อย่าลืมว่าทุกโซลูชันมาพร้อมกับช่วงการเรียนรู้ของตนเอง แต่ผลประโยชน์ที่คุณได้รับจากการทดสอบที่สะอาดและโดดเด่นนั้นมีค่ามาก
ให้ความสำคัญกับการจัดการเวลาในระหว่างการทดสอบ แล้วคุณจะเห็นคุณภาพของโค้ดและการทดสอบของคุณดีขึ้นอย่างมาก!