पीडीआर के उत्तर के लिए अधिक व्यावहारिक दृष्टिकोण लेना । TDD परीक्षण के बजाय सॉफ़्टवेयर डिज़ाइन के बारे में है। आप अपने काम को सत्यापित करने के लिए यूनिट टेस्ट का उपयोग करते हैं।
तो एक इकाई परीक्षण स्तर पर आपको इकाइयों को डिजाइन करने की आवश्यकता होती है ताकि उन्हें पूरी तरह से निर्धारक फैशन में परीक्षण किया जा सके। आप ऐसा कुछ भी करके कर सकते हैं जो इकाई को बिना शर्त (जैसे एक यादृच्छिक संख्या जनरेटर) और सार को दूर करता है। कहो कि हमारे पास एक तरीका है, जो यह तय करने का एक अच्छा उदाहरण है कि कोई चाल अच्छी है या नहीं:
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
वर्ग अब अपने अमूर्त, यानी इंटरफ़ेस के माध्यम से ठोस वर्ग का उपयोग करने की जरूरत है। चीजों को करने के इस तरीके को निर्भरता इंजेक्शन कहा जाता है (नीचे दिया गया उदाहरण कंस्ट्रक्टर इंजेक्शन का एक उदाहरण है, लेकिन आप इसे सेटर के साथ भी कर सकते हैं):
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
"अनुबंध" के बाद है। आप इसके लिए एक नकली रूपरेखा का उपयोग कर सकते हैं, लेकिन यह उदाहरण अपने आप को कोड करने के लिए पर्याप्त सरल है:
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));
}
आशा है कि यह आपको अपने आवेदन को डिज़ाइन करने के तरीके के बारे में विचार देता है ताकि क्रमपरिवर्तन को मजबूर किया जा सके ताकि आप सभी किनारे के मामलों और व्हाट्सन का परीक्षण कर सकें।