การสร้างวัตถุด้วยพารามิเตอร์ null ในการทดสอบหน่วยตกลงหรือไม่


37

ฉันเริ่มเขียนการทดสอบหน่วยสำหรับโครงการปัจจุบันของฉัน ฉันไม่ได้มีประสบการณ์กับมันจริงๆ ฉันต้องการ "รับ" อย่างสมบูรณ์ดังนั้นฉันจึงไม่ใช้เฟรมเวิร์ก IoC หรือไลบรารีที่เยาะเย้ย

ฉันสงสัยว่ามีอะไรผิดปกติหรือเปล่ากับการให้อาร์กิวเมนต์ที่เป็นโมฆะแก่ตัวสร้างวัตถุในการทดสอบหน่วย ให้ฉันให้รหัสตัวอย่าง:

public class CarRadio
{...}


public class Motor
{
    public void SetSpeed(float speed){...}
}


public class Car
{
    public Car(CarRadio carRadio, Motor motor){...}
}


public class SpeedLimit
{
    public bool IsViolatedBy(Car car){...}
}

แต่อีกตัวอย่างรหัสรถยนต์ (TM) ได้ลดเหลือเพียงบางส่วนที่สำคัญสำหรับคำถาม ตอนนี้ฉันเขียนการทดสอบแบบนี้:

public class SpeedLimitTest
{
    public void TestSpeedLimit()
    {
        Motor motor = new Motor();
        motor.SetSpeed(10f);
        Car car = new Car(null, motor);

        SpeedLimit speedLimit = new SpeedLimit();
        Assert.IsTrue(speedLimit.IsViolatedBy(car));
    }
}

การทดสอบทำงานได้ดี SpeedLimitต้องการ a Carด้วยMotorเพื่อทำสิ่งนั้น มันไม่ได้สนใจCarRadioเลยดังนั้นฉันจึงให้ null สำหรับสิ่งนั้น

ฉันสงสัยว่าวัตถุที่มีฟังก์ชั่นการทำงานที่ถูกต้องโดยไม่ถูกสร้างขึ้นอย่างสมบูรณ์เป็นการละเมิด SRP หรือกลิ่นรหัส ฉันมีความรู้สึกที่ดุด่าเช่นนี้ แต่speedLimit.IsViolatedBy(motor)ก็ไม่รู้สึกถูกต้องเช่นกัน - การ จำกัด ความเร็วถูกละเมิดโดยรถยนต์ไม่ใช่มอเตอร์ บางทีฉันอาจต้องการมุมมองที่แตกต่างกันสำหรับการทดสอบหน่วยเทียบกับรหัสการทำงานเพราะความตั้งใจทั้งหมดคือการทดสอบเพียงบางส่วนเท่านั้น

การสร้างวัตถุที่มีค่า Null ในหน่วยทดสอบกลิ่นของรหัสหรือไม่?


24
ปิดหัวข้อเล็กน้อย แต่Motorอาจไม่ควรมีspeedเลย มันควรจะมีthrottleและคำนวณtorqueขึ้นอยู่กับปัจจุบันและrpm throttleมันเป็นหน้าที่ของรถที่จะใช้ a Transmissionเพื่อรวมเข้ากับความเร็วปัจจุบันและเพื่อเปลี่ยนเป็นrpmสัญญาณกลับไปที่Motor... แต่ฉันเดาว่าคุณไม่ได้อยู่ในความเป็นจริงแล้วใช่ไหม?
cmaster

17
กลิ่นรหัสคือคอนสตรัคเตอร์ของคุณใช้ค่า null โดยไม่บ่นในตอนแรก หากคุณคิดว่าสิ่งนี้เป็นสิ่งที่ยอมรับได้ (คุณอาจมีเหตุผลในเรื่องนี้): ลองทดสอบดูสิ!
ทอมมี่

4
พิจารณารูปแบบ Null วัตถุ มันมักจะทำให้รหัสง่ายขึ้นในขณะที่ยังทำให้มันปลอดภัย NPE
Bakuriu

17
ขอแสดงความยินดี : คุณทดสอบด้วยnullวิทยุแล้วการ จำกัด ความเร็วจะคำนวณอย่างถูกต้อง ตอนนี้คุณอาจต้องการสร้างการทดสอบเพื่อตรวจสอบการ จำกัด ความเร็วด้วยวิทยุ ในกรณีที่พฤติกรรมแตกต่าง ...
Matthieu M.

3
ไม่แน่ใจเกี่ยวกับตัวอย่างนี้ แต่บางครั้งความจริงที่ว่าคุณเพียงแค่ต้องการทดสอบครึ่งชั้นเป็นเบาะแสว่ามีบางสิ่งที่จะพัง
โอเวน

คำตอบ:


70

ในกรณีของตัวอย่างข้างต้นนั้นมันเป็นสิ่งที่เหมาะสมที่สามารถอยู่ได้โดยไม่ต้องCar CarRadioในกรณีนี้ฉันจะบอกว่าไม่เพียง แต่เป็นที่ยอมรับได้ที่จะผ่านเป็นโมฆะCarRadioบางครั้งฉันจะบอกว่ามันเป็นข้อบังคับ การทดสอบของคุณต้องมั่นใจว่าการใช้งานCarคลาสนั้นแข็งแกร่งและไม่ส่งข้อยกเว้นตัวชี้ null เมื่อไม่มีCarRadioอยู่

แต่ขอนำตัวอย่างที่แตกต่างกัน - SteeringWheelขอพิจารณา สมมติว่า a Carต้องมีSteeringWheelแต่การทดสอบความเร็วไม่ได้สนใจเลย ในกรณีนี้ฉันจะไม่ผ่านค่า null SteeringWheelเนื่องจากเป็นการผลักCarชั้นเรียนไปยังที่ที่ไม่ได้ออกแบบมา ในกรณีนี้คุณควรที่จะสร้างการเรียงลำดับที่ดีกว่าDefaultSteeringWheel(เพื่อใช้การเปรียบเทียบต่อไป) ถูกล็อคเป็นเส้นตรง


44
และไม่ลืมที่จะเขียนหน่วยทดสอบเพื่อตรวจสอบว่าCarไม่สามารถสร้างได้โดยไม่ต้องSteeringWheel...
cmaster

13
ฉันอาจจะหายไปบางสิ่งบางอย่าง แต่ถ้าเป็นไปได้และเป็นเรื่องธรรมดาที่จะสร้างแบบCarไม่มีCarRadioมันจะไม่มีเหตุผลที่จะสร้างนวกรรมิกที่ไม่ต้องการให้ส่งผ่านและไม่ต้องกังวลเกี่ยวกับ null ที่ชัดเจนเลย ?
Earwig

16
รถยนต์ที่ขับขี่ด้วยตนเองอาจไม่มีพวงมาลัย แค่พูด. ☺
BlackJack

1
@James_Parsons ฉันลืมที่จะเพิ่มว่ามันเป็นเรื่องเกี่ยวกับชั้นเรียนที่ไม่ได้มีการตรวจสอบโมฆะเพราะมันใช้เฉพาะภายในและได้รับพารามิเตอร์ที่ไม่ใช่โมฆะเสมอ วิธีอื่น ๆ ของCarจะได้โยน NRE ด้วย null CarRadioแต่รหัสที่เกี่ยวข้องสำหรับSpeedLimitจะไม่ ในกรณีของคำถามตามที่โพสต์ตอนนี้คุณจะถูกต้องและฉันจะทำเช่นนั้นแน่นอน
R. Schmitz

2
@traceur วิธีที่ทุกคนคิดว่าคลาสที่อนุญาตให้สร้างด้วยอาร์กิวเมนต์ null หมายความว่า null เป็นตัวเลือกที่ถูกต้องทำให้ฉันรู้ว่าฉันน่าจะมีเช็คว่าง ปัญหาที่แท้จริงที่ฉันจะได้รับนั้นถูกครอบคลุมด้วยคำตอบที่ดีน่าสนใจและเป็นลายลักษณ์อักษรมากมายที่นี่ซึ่งฉันไม่ต้องการทำลายและช่วยฉันได้ ยังยอมรับคำตอบนี้ในตอนนี้เพราะฉันไม่ชอบที่จะทิ้งสิ่งที่ยังไม่เสร็จและมันเป็นสิ่งที่ upvoted ที่สุด (แม้ว่าพวกเขาทั้งหมดจะเป็นประโยชน์)
R. Schmitz

23

การสร้างวัตถุที่มีค่า Null ในหน่วยทดสอบกลิ่นของรหัสหรือไม่?

ใช่. สังเกตคำจำกัดความของรหัสกลิ่น C2 : "CodeSmell เป็นคำใบ้ว่ามีบางอย่างผิดพลาดไม่ใช่ความแน่นอน"

การทดสอบทำงานได้ดี SpeedLimit ต้องการรถยนต์ที่มีมอเตอร์เพื่อทำสิ่งนี้ มันไม่ได้สนใจ CarRadio เลยดังนั้นฉันจึงให้ null สำหรับสิ่งนั้น

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

หากเป็นไปได้มากกว่าที่คุณกำลังพยายามช่วยตัวเองในการสร้างสิ่งCarRadioที่คุณรู้ว่าไม่ได้ใช้ในกรณีนี้คุณควรสังเกตว่า

  • นี่เป็นการละเมิด encapsulation (คุณปล่อยให้ความจริงที่CarRadioว่าไม่ได้ใช้รั่วไหลออกมาทดสอบ)
  • คุณได้ค้นพบอย่างน้อยหนึ่งกรณีที่คุณต้องการสร้าง a Carโดยไม่ได้ระบุCarRadio

ฉันสงสัยอย่างยิ่งว่ารหัสกำลังพยายามบอกคุณว่าคุณต้องการตัวสร้างที่ดูเหมือน

public Car(IMotor motor) {...}

จากนั้นตัวสร้างสามารถตัดสินใจว่าจะทำอย่างไรกับความจริงที่ว่าไม่มีCarRadio

public Car(IMotor motor) {
    this(null, motor);
}

หรือ

public Car(IMotor motor) {
    this( new ICarRadio() {...} , motor);
}

หรือ

public Car(IMotor motor) {
    this( new DefaultRadio(), motor);
}

เป็นต้น

มันเกี่ยวกับถ้าผ่าน null ไปอย่างอื่นในขณะที่การทดสอบ SpeedLimit คุณจะเห็นว่าการทดสอบนั้นเรียกว่า "SpeedLimitTest" และ Assert เดียวเท่านั้นที่กำลังตรวจสอบวิธีการของ SpeedLimit

นั่นคือกลิ่นที่น่าสนใจที่สอง - เพื่อทดสอบ SpeedLimit คุณต้องสร้างรถทั่วทั้งวิทยุแม้ว่าสิ่งเดียวที่เช็ค SpeedLimit อาจใส่ใจเกี่ยวกับการเป็นความเร็ว

นี่อาจเป็นคำใบ้ที่SpeedLimit.isViolatedByควรยอมรับอินเทอร์เฟซบทบาทที่รถยนต์ใช้แทนที่จะต้องใช้ทั้งรถ

interface IHaveSpeed {
    float speed();
}

class Car implements IHaveSpeed {...}

IHaveSpeedเป็นชื่อที่มีหมัดจริงๆ; หวังว่าภาษาโดเมนของคุณจะมีการปรับปรุง

เมื่อใช้อินเทอร์เฟซนั้นการทดสอบของคุณSpeedLimitจึงง่ายกว่ามาก

public void TestSpeedLimit()
{
    IHaveSpeed somethingTravelingQuickly = new IHaveSpeed {
        float speed() { return 10f; }
    }

    SpeedLimit speedLimit = new SpeedLimit();
    Assert.IsTrue(speedLimit.IsViolatedBy(somethingTravelingQuickly));
}

ในตัวอย่างสุดท้ายของคุณฉันคิดว่าคุณต้องสร้างคลาสจำลองที่ใช้IHaveSpeedอินเทอร์เฟซเป็น (อย่างน้อยใน c #) คุณจะไม่สามารถสร้างอินเทอร์เฟซให้เองได้
Ryan Searle

1
ถูกต้อง - การสะกดคำที่มีประสิทธิภาพจะขึ้นอยู่กับรสชาติของ Blub ที่คุณใช้สำหรับการทดสอบ
VoiceOfUnreason

18

การสร้างวัตถุที่มีค่า Null ในหน่วยทดสอบกลิ่นของรหัสหรือไม่?

ไม่

ไม่ใช่เลย. หากNULLเป็นค่าที่ใช้เป็นอาร์กิวเมนต์ (บางภาษาอาจมีโครงสร้างที่ไม่อนุญาตให้ส่งผ่านตัวชี้โมฆะ) คุณควรทดสอบ

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

ดังนั้นหากรถของคุณควรจะสร้างได้โดยไม่มีวิทยุคุณควรเขียนแบบทดสอบ หากไม่ใช่และควรจะมีข้อยกเว้นคุณควรเขียนการทดสอบ

ทั้งสองวิธีใช่คุณควรNULLเขียนทดสอบสำหรับ มันจะเป็นกลิ่นรหัสถ้าคุณทิ้งมันไว้ นั่นหมายความว่าคุณมีรหัสสาขาที่ยังไม่ผ่านการทดสอบซึ่งคุณเพิ่งสันนิษฐานว่าไม่มีข้อผิดพลาดอย่างน่าอัศจรรย์


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


ดูเหมือนว่าคุณกำลังเขียนการแข่งขันทดสอบCarที่นี่ SpeedLimitขณะที่ฉันไม่เห็นอะไรที่ฉันต้องการพิจารณาคำสั่งที่ไม่ถูกต้องเป็นคำถามที่เกี่ยวกับการทดสอบ
R. Schmitz

@ R.Schmitz ไม่แน่ใจว่าคุณหมายถึงอะไร ผมได้ยกคำถามที่ว่ามันเป็นเรื่องของการส่งผ่านไปยังตัวสร้างของNULL Car
nvoigt

1
มันเกี่ยวกับถ้าผ่าน null ไปเป็นอย่างอื่นในขณะที่การทดสอบ SpeedLimitคุณจะเห็นว่าการทดสอบที่เรียกว่า "SpeedLimitTest" และเป็นสิ่งเดียวคือการตรวจสอบวิธีการของAssert SpeedLimitการทดสอบCar- เช่น "ถ้ารถของคุณควรจะสร้างได้โดยไม่มีวิทยุคุณควรเขียนแบบทดสอบ" - จะเกิดขึ้นในการทดสอบอื่น
R. Schmitz

7

โดยส่วนตัวฉันจะลังเลที่จะฉีดว่าง ในความเป็นจริงเมื่อใดก็ตามที่ฉันฉีดการพึ่งพาเป็นตัวสร้างหนึ่งในสิ่งแรกที่ฉันทำคือการเพิ่ม ArgumentNullException ถ้าการฉีดเหล่านั้นเป็นโมฆะ ด้วยวิธีนี้ฉันสามารถใช้พวกเขาอย่างปลอดภัยภายในชั้นเรียนของฉันโดยไม่มีการตรวจสอบโมฆะนับสิบรอบ นี่เป็นรูปแบบที่ธรรมดามาก สังเกตการใช้งานแบบอ่านอย่างเดียวเพื่อให้แน่ใจว่าการขึ้นต่อกันที่กำหนดไว้ในตัวสร้างไม่สามารถตั้งค่าเป็นโมฆะ (หรืออะไรก็ได้) ภายหลัง:

class Car
{
   private readonly ICarRadio _carRadio;
   private readonly IMotor _motor;

   public Car(ICarRadio carRadio, IMotor motor)
   {
      if (carRadio == null)
         throw new ArgumentNullException(nameof(carRadio));

      if (motor == null)
         throw new ArgumentNullException(nameof(motor));

      _carRadio = carRadio;
      _motor = motor;
   }
}

จากข้างต้นฉันอาจได้รับการทดสอบหน่วยหรือสองที่ฉันฉีด nulls เพียงเพื่อให้แน่ใจว่าการตรวจสอบโมฆะของฉันทำงานตามที่คาดไว้

ต้องบอกว่านี่กลายเป็นประเด็นที่ไม่ใช่ปัญหาเมื่อคุณทำสองสิ่ง:

  1. โปรแกรมไปยังอินเตอร์เฟสแทนคลาส
  2. ใช้กรอบการเยาะเย้ย (เช่น Moq สำหรับ C #) เพื่อฉีดการอ้างอิงที่เยาะเย้ยแทนที่จะเป็นโมฆะ

ดังนั้นสำหรับตัวอย่างของคุณ:

interface ICarRadio
{
   bool Tune(float frequency);
}

interface Motor
{
   bool SetSpeed(float speed);
}

...
var car = new Car(new Moq<ICarRadio>().Object, new Moq<IMotor>().Object);

รายละเอียดเพิ่มเติมเกี่ยวกับการใช้ขั้นต่ำที่สามารถพบได้ที่นี่

แน่นอนถ้าคุณต้องการที่จะเข้าใจโดยไม่ต้องเยาะเย้ยก่อนคุณยังสามารถทำได้ตราบใดที่คุณกำลังใช้อินเทอร์เฟซ เพียงแค่สร้างหุ่นจำลอง CarRadio และมอเตอร์ดังต่อไปนี้แล้วฉีดแทน:

class DummyCarRadio : ICarRadio
{
   ...
}
class DummyMotor : IMotor
{
   ...
}

...
var car = new Car(new DummyCarRadio(), new DummyMotor())

3
นี่คือคำตอบที่ฉันจะเขียน
Liath

1
ฉันจะไปไกลเพื่อบอกว่าวัตถุจำลองก็ต้องทำตามสัญญาด้วย หากIMotorมีgetSpeed()วิธีการDummyMotorก็จะต้องกลับมาแก้ไขความเร็วหลังจากประสบความสำเร็จsetSpeedเช่นกัน
ComFreek

1

มันไม่ได้เป็นเพียงแค่โอเค แต่เป็นเทคนิคการแบ่งการพึ่งพาที่รู้จักกันดีสำหรับการรับรหัสดั้งเดิมในการทดสอบเทียม (ดู“ การทำงานอย่างมีประสิทธิภาพด้วยรหัสมรดก” โดย Michael Feathers)

มันมีกลิ่นไหม ดี...

การทดสอบไม่มีกลิ่น การทดสอบกำลังทำงานอยู่ มีการประกาศว่า "วัตถุนี้อาจเป็นโมฆะและรหัสที่อยู่ระหว่างการทดสอบยังคงทำงานได้อย่างถูกต้อง"

กลิ่นอยู่ในการดำเนินการ เมื่อประกาศอาร์กิวเมนต์ตัวสร้างคุณจะประกาศว่า“ คลาสนี้ต้องการสิ่งนี้เพื่อให้สามารถทำงานได้อย่างถูกต้อง” เห็นได้ชัดว่ามันไม่จริง สิ่งที่ไม่จริงเป็นเพียงเล็กน้อยส่งกลิ่น


1

ลองย้อนกลับไปสู่หลักการแรก

การทดสอบหน่วยทดสอบลักษณะบางอย่างของชั้นเดียว

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

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

จนถึงตอนนี้ดีมาก อย่างไรก็ตามถ้า NULL ไม่ใช่ค่าที่ถูกต้อง ดีที่นี่คุณเข้าสู่โลกมืดของmocks, ต้นขั้วหุ่นและปลอม

ถ้าทั้งหมดนี้ดูเหมือนจะใช้เวลามากคุณก็ใช้หุ่นจำลองโดยการส่ง NULL ในตัวสร้างรถยนต์เนื่องจากเป็นค่าที่อาจไม่ใช้

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


1
"การทดสอบหน่วยสำหรับการทดสอบรหัสของคลาสเดียว" ถอนหายใจ นั่นไม่ใช่สิ่งที่การทดสอบหน่วยและการปฏิบัติตามแนวทางนั้นจะนำคุณไปสู่ชั้นเรียนป่องหรือการต่อต้านการทดสอบขัดขวาง
Ant P

3
การรักษา "หน่วย" เป็นคำสละสลวยสำหรับ "คลาส" นั้นเป็นวิธีที่ใช้กันโดยทั่วไป แต่ในความเป็นจริงแล้วสิ่งทั้งหมดนี้คือ (ก) สนับสนุนการทดสอบ "ขยะมูลฝอยขยะ" ซึ่งอาจบ่อนทำลายความถูกต้องของการทดสอบทั้งหมด suite และ (b) บังคับใช้ขอบเขตที่ควรมีอิสระในการเปลี่ยนแปลงซึ่งสามารถทำลายประสิทธิภาพการผลิต ฉันหวังว่าผู้คนจำนวนมากจะฟังความเจ็บปวดของพวกเขาและท้าทายความคิดก่อนหน้านี้
Ant P

3
ไม่มีความสับสน ทดสอบหน่วยของพฤติกรรมไม่ใช่หน่วยของรหัส ไม่มีอะไรเกี่ยวกับแนวคิดของการทดสอบหน่วย - ยกเว้นในกลุ่มลัทธิการขนส่งสินค้าที่แพร่หลายของการทดสอบซอฟต์แวร์ - ซึ่งบอกเป็นนัยว่าหน่วยทดสอบนั้นเชื่อมโยงกับแนวคิด OOP ที่ชัดเจนของชั้นเรียน และความเข้าใจผิดที่สร้างความเสียหายเช่นกัน
Ant P

1
ฉันไม่แน่ใจอย่างแม่นยำในสิ่งที่คุณหมายถึง - ฉันเถียงตรงข้ามกับสิ่งที่คุณพูดถึง ขอบเขต Stub / เยาะเย้ยยาก (ถ้าคุณต้อง) และทดสอบหน่วยพฤติกรรม ผ่าน API สาธารณะ API นั้นขึ้นอยู่กับว่าคุณกำลังสร้างอะไร แต่รอยเท้าควรจะน้อยที่สุด การเพิ่ม Abstraction, Polymorphism หรือ Code ในการปรับโครงสร้างไม่ควรทำให้การทดสอบล้มเหลว - "หน่วยต่อคลาส" ขัดแย้งกับสิ่งนี้และทำลายคุณค่าของการทดสอบอย่างเต็มที่ในตอนแรก
Ant P

1
RobbieDee - ฉันกำลังพูดถึงสิ่งที่ตรงกันข้าม พิจารณาว่าคุณอาจเป็นคนที่มีความเข้าใจผิดทั่วไปทบทวนสิ่งที่คุณคิดว่าเป็น“ หน่วย” และอาจขุดลึกลงไปในสิ่งที่ Kent Beck พูดจริง ๆ แล้วเมื่อเขาพูดถึง TDD สิ่งที่คนส่วนใหญ่เรียกว่า TDD ตอนนี้เป็นสิ่งที่น่ากลัวมาก youtube.com/watch?v=EZ05e7EMOLM
Ant P

1

การดูที่การออกแบบของคุณผมขอแนะนำว่าประกอบด้วยชุดของCar Featuresคุณลักษณะที่อาจจะเป็นCarRadioหรือEntertainmentSystemซึ่งอาจประกอบด้วยสิ่งที่ต้องการCarRadio, DvdPlayerฯลฯ

ดังนั้นอย่างน้อยคุณจะต้องสร้างด้วยชุดของCar และจะเป็น implementers ของอินเตอร์เฟส (Java, C # ฯลฯ ) ของและนี่จะเป็นตัวอย่างของรูปแบบการออกแบบคอมโพสิตFeaturesEntertainmentSystemCarRadiopublic [I|i]nterface Feature

ดังนั้นคุณมักจะสร้างCarด้วยFeaturesและการทดสอบหน่วยจะไม่ยกตัวอย่างโดยไม่ต้องมีCar Featuresแม้ว่าคุณอาจพิจารณาการเยาะเย้ย a BasicTestCarFeatureSetที่มีฟังก์ชั่นการทำงานขั้นต่ำที่จำเป็นสำหรับการทดสอบพื้นฐานของคุณ

แค่ความคิดบางอย่าง

จอห์น

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