การทดสอบหน่วย:“ มันเป็นกลิ่นรหัสหากคุณทำการปรับโครงสร้างใหม่และไม่มีผู้ทำงานร่วมกัน”?


9

ฉันกำลังอ่านศิลปะของการทดสอบหน่วยโดย Roy Osherove ฉันอยู่ที่หัวข้อ 7.2 การเขียนแบบทดสอบที่คงไว้ซึ่งผู้เขียนมีหมายเหตุเกี่ยวกับกลิ่นรหัสนี้:

หมายเหตุ: เมื่อคุณ refactor สถานะภายในที่จะมองเห็นได้จากการทดสอบภายนอกอาจถือได้ว่าเป็นกลิ่นรหัส (สัญญาณว่ามีบางอย่างผิดปกติในการออกแบบหรือตรรกะของรหัส) มันไม่ได้เป็นกลิ่นรหัสเมื่อคุณ refactoring เปิดเผยผู้ทำงานร่วมกัน มันเป็นกลิ่นรหัสหากคุณทำการปรับโครงสร้างใหม่และไม่มีผู้ทำงานร่วมกัน

แก้ไข : สิ่งที่ผู้เขียนหมายถึงโดย "ผู้ทำงานร่วมกัน" คือการพึ่งพา ตัวอย่างบางส่วนของเขาสำหรับการพึ่งพาคือคลาสที่เข้าถึงฐานข้อมูลหรือเข้าถึงระบบไฟล์ของระบบปฏิบัติการ นี่คือที่ซึ่งเขากำหนดต้นขั้วและเริ่มใช้คำทำงานร่วมกัน:

ต้นขั้วเป็นแทนควบคุมที่มีอยู่การพึ่งพา (หรือ ทำงานร่วมกัน ) ในระบบ

ผู้เขียนไม่มีตัวอย่างของกลิ่นรหัสนี้และฉันมีปัญหาในการทำความเข้าใจ / นึกภาพว่ามันจะเป็นอย่างไร บางคนสามารถอธิบายสิ่งนี้ได้มากกว่านี้เล็กน้อยและอาจเป็นตัวอย่างที่ชัดเจน?


ฉันคิดว่าความสับสนที่นี่เกิดจากคำว่า "ผู้ทำงานร่วมกัน" ฉันต้องยอมรับว่าฉันไม่แน่ใจว่าเขาหมายถึงอะไรในบริบทนี้เช่นกัน
rossipedia

@Bryan Ross ฉันอัปเดตโพสต์ด้วยวิธีที่ผู้เขียนใช้คำว่า "ผู้ทำงานร่วมกัน" ขอบคุณ!
โปรแกรมเมอร์

คำตอบ:


3

ฉันคิดว่านี่คือสิ่งที่ผู้เขียนกำลังทำ

ในตัวอย่างรหัสของฉันฉันมีหน้าต่างเวลาที่ใช้ปริมาณผลผลิตบวกเวลาเริ่มต้นและหยุด ความตั้งใจคือการวาดหน้าต่างผลลัพธ์ในช่วงเวลา 24 ชั่วโมง ริ้วรอยจะถูกเพิ่มเมื่อเวลาเริ่มต้นมากกว่าเวลาหยุดเพราะนั่นคือหน้าต่างเวลาที่ครอบคลุมถึงเที่ยงคืน

คุณสามารถเขียนการทดสอบหน่วยที่ออกกำลังกายวัตถุโดยไม่ต้องเปิดเผยตัวแปรส่วนตัว Bools และ timespans ส่วนตัวเหล่านั้นคือผู้ทำงานร่วมกันที่เขาอ้างถึงเมื่อเปิดเผย internals สำหรับการทดสอบหน่วย ตามหนังสือเล่มนี้การเปิดเผยตัวผู้ฝึกงานเหล่านั้นจะไม่ได้กลิ่นรหัสเพราะพวกเขาเป็นผู้ทำงานร่วมกัน

การเปิดเผยสองครั้งoutputนั้นจะเป็นกลิ่นรหัสเนื่องจากไม่ใช่ผู้ทำงานร่วมกัน - เป็นองค์ประกอบที่ซ่อนไว้อย่างชัดเจนโดยคลาสตัวเองที่มีตรรกะแบบมีเงื่อนไขภายในGetOutputเพื่อกำหนดสิ่งที่ควรส่งคืน

การขุดเข้าไปใน bools / timespans จะทำให้การทดสอบหน่วยครอบคลุมมากขึ้น เขาบอกว่านี่เป็นสิ่งที่ดี
การขุดลงไปเป็นสองเท่าoutputจะต้องใช้ตรรกะเพิ่มเติมในการทดสอบหน่วยของคุณซึ่งสะท้อนสิ่งที่GetOutputกำลังทำอยู่ นี่จะเป็นกลิ่นรหัสที่เขาอ้างถึง

TimeWindow ระดับสาธารณะ
{
  บูลส่วนตัว isConst;
  บูลส่วนตัวครอบคลุมช่วงกลางคืน
  TimeSpan ส่วนตัว start1;
  TimeSpan ส่วนตัว stop1;
  TimeSpan ส่วนตัว start2;
  TimeSpan ส่วนตัว stop2;
  เอาต์พุตคู่ส่วนตัว

  พับลิก TimeWindow สาธารณะ (ดับเบิ้ลออก, เริ่มใช้ TimeSpan, หยุด TimeSpan)
  {
    เอาท์พุท = ออก;

    ถ้า (เริ่ม == หยุด)
      isConst = true;
    อื่นถ้า (เริ่ม> หยุด)
    {
      spansMidnight = true;
      start1 = เที่ยงคืน;
      stop1 = หยุด;
      start2 = เริ่ม;
      stop2 = เที่ยงคืน
    }
    อื่น 
    {
      start1 = เริ่ม;
      stop1 = หยุด;
    }
  }

  สาธารณะสองครั้ง GetOutput (TimeSpan เวลา)
  {
    // ตรรกะบางอย่างที่นี่เกี่ยวกับสิ่งที่ / คืน
    ...
    เอาท์พุทกลับมา;
  }

}

0

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

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

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