ใช้แนวทางปฏิบัติที่เป็นประโยชน์มากขึ้นในการตอบของ pdrตอบของสาธารณรัฐประชาธิปไตยประชาชนลาวTDD นั้นเกี่ยวกับการออกแบบซอฟต์แวร์มากกว่าการทดสอบ คุณใช้การทดสอบหน่วยเพื่อตรวจสอบงานของคุณในขณะที่คุณไป
ดังนั้นในระดับการทดสอบหน่วยคุณจำเป็นต้องออกแบบหน่วยเพื่อที่จะสามารถทดสอบได้ในแบบที่กำหนดไว้อย่างสมบูรณ์ คุณสามารถทำได้โดยการทำสิ่งใดก็ตามที่ทำให้หน่วย nondeterministic (เช่นตัวสร้างตัวเลขสุ่ม) และนามธรรมออกไป สมมติว่าเรามีตัวอย่างที่ไร้เดียงสาของวิธีการตัดสินใจว่าการเคลื่อนไหวดีหรือไม่:
class Decider {
public boolean decide(float input, float risk) {
float inputRand = Math.random();
if (inputRand > input) {
float riskRand = Math.random();
}
return false;
}
}
// The usage:
Decider d = new Decider();
d.decide(0.1337f, 0.1337f);
วิธีนี้ยากมากที่จะทดสอบและสิ่งเดียวที่คุณสามารถตรวจสอบได้ในการทดสอบหน่วยคือขอบเขต ... แต่ต้องใช้ความพยายามอย่างมากในการทดสอบ ดังนั้นเรามาสรุปส่วนการสุ่มโดยการสร้างส่วนต่อประสานและคลาสที่เป็นรูปธรรมที่ล้อมรอบฟังก์ชันการทำงาน:
public interface IRandom {
public float random();
}
public class ConcreteRandom implements IRandom {
public float random() {
return Math.random();
}
}
Decider
ระดับขณะนี้ความต้องการที่จะใช้ชั้นคอนกรีตผ่านนามธรรมของมันคือการเชื่อมต่อ วิธีการทำสิ่งนี้เรียกว่าการฉีดพึ่งพา (ตัวอย่างด้านล่างเป็นตัวอย่างของการฉีดคอนสตรัคเตอร์ แต่คุณสามารถทำได้ด้วย setter เช่นกัน):
class Decider {
IRandom irandom;
public Decider(IRandom irandom) { // constructor injection
this.irandom = irandom;
}
public boolean decide(float input, float risk) {
float inputRand = irandom.random();
if (inputRand > input) {
float riskRand = irandom.random();
}
return false;
}
}
// The usage:
Decider d = new Decider(new ConcreteRandom);
d.decide(0.1337f, 0.1337f);
คุณอาจถามตัวเองว่าทำไม "การขยายโค้ด" นี้จึงเป็นสิ่งจำเป็น สำหรับผู้เริ่มต้นตอนนี้คุณสามารถเยาะเย้ยพฤติกรรมของส่วนที่สุ่มของอัลกอริทึมเพราะDecider
ตอนนี้มีการพึ่งพาที่เป็นไปตามIRandom
สัญญา "s" คุณสามารถใช้กรอบการเยาะเย้ยสำหรับสิ่งนี้ แต่ตัวอย่างนี้ง่ายพอที่จะให้รหัสตัวเอง:
class MockedRandom() implements IRandom {
public List<Float> floats = new ArrayList<Float>();
int pos;
public void addFloat(float f) {
floats.add(f);
}
public float random() {
float out = floats.get(pos);
if (pos != floats.size()) {
pos++;
}
return out;
}
}
ส่วนที่ดีที่สุดคือสิ่งนี้สามารถแทนที่การใช้งานจริง "จริง" ได้อย่างสมบูรณ์ รหัสกลายเป็นเรื่องง่ายที่จะทดสอบเช่นนี้:
@Before void setUp() {
MockedRandom mRandom = new MockedRandom();
Decider decider = new Decider(mRandom);
}
@Test
public void testDecisionWithLowInput_ShouldGiveFalse() {
mRandom.addFloat(0f);
assertFalse(decider.decide(0.1337f, 0.1337f));
}
@Test
public void testDecisionWithHighInputRandButLowRiskRand_ShouldGiveFalse() {
mRandom.addFloat(1f);
mRandom.addFloat(0f);
assertFalse(decider.decide(0.1337f, 0.1337f));
}
@Test
public void testDecisionWithHighInputRandAndHighRiskRand_ShouldGiveTrue() {
mRandom.addFloat(1f);
mRandom.addFloat(1f);
assertTrue(decider.decide(0.1337f, 0.1337f));
}
หวังว่านี่จะช่วยให้คุณมีความคิดเกี่ยวกับวิธีการออกแบบแอปพลิเคชันของคุณเพื่อให้การเรียงสับเปลี่ยนสามารถบังคับใช้เพื่อให้คุณสามารถทดสอบทุกกรณีและสิ่งที่ขอบ