อาคารในคำตอบของคริสเตียนที่ดีที่สุดของความรู้ของฉันตะเข็บระยะไม่มาจากหนังสือ Feathers' การทำงานอย่างมีประสิทธิภาพกับรหัสมรดก คำจำกัดความอยู่ในหน้า 31:
ตะเข็บเป็นสถานที่ที่คุณสามารถเปลี่ยนพฤติกรรมในโปรแกรมของคุณโดยไม่ต้องแก้ไขในสถานที่นั้น
เพื่อให้ตัวอย่างของสิ่งที่ตะเข็บและมันคืออะไรไม่พิจารณารหัส Java ต่อไปนี้:
public class MyClass {
private final Foo foo;
public MyClass(Foo foo) {
this.foo = foo;
}
public void doBunchOfStuff(BarFactory barFactory) {
// foo.doStuff() is a seam because I can inject a mock instance of Foo
this.foo.doStuff();
// barFactory.makeBars() is a seam because I can replace the default
// BarFactory instance with something else during testing
List<Bar> bars = barFactory.makeBars();
for(Bar bar : bars) {
// bar.cut() is also a seam because if I can mock out BarFactory, then
// I can get the mocked BarFactory to return mocked Bars.
bar.cut();
}
// MyStaticClass.staticCall() is not a seam because I cannot replace
// staticCall() with different behavior without calling a class besides
// MyStaticClass, or changing the code in MyStaticClass.
MyStaticClass.staticCall();
// This is not a seam either because I can't change the behavior of what
// happens when instanceCall() occurs with out changing this method or
// the code in instanceCall().
(new MyInstanceClass()).instanceCall();
}
}
ตะเข็บแบบสุดขั้วด้านบนจะเป็นตะเข็บเว้นแต่:
- คลาสที่ถูกฉีดถือเป็นที่สิ้นสุด
- วิธีการที่ถูกเรียกนั้นถือเป็นที่สุด
โดยทั่วไปตะเข็บช่วยในการทดสอบหน่วย ฉันไม่สามารถเขียนการทดสอบหน่วยสำหรับMyClass
เนื่องจากสายไปและMyStaticClass.staticCall()
(new MyInstanceClass()).instanceCall()
ทดสอบหน่วยใด ๆ สำหรับMyClass
's doBunchOfStuff()
วิธีการจะต้องมีการทดสอบMyStaticClass.staticCall()
และ(new MyInstanceClass()).instanceCall()
และทุกการอ้างอิงของพวกเขาที่ได้รับการเรียก ในทางกลับกันโดยการใช้คลาสที่ไม่เป็นขั้นสุดท้ายด้วยวิธีที่ไม่เป็นขั้นสุดท้าย (หรือดีกว่า - อินเทอร์เฟซ) อินสแตนซ์ที่ถูกฉีดของFoo
และBarFactory
ทำการทดสอบหน่วยเพื่อMyClass
ให้สามารถเขียนได้โดยการเยาะเย้ย