मैं अपनी यूनिट परीक्षणों के बारे में बढ़ती परेशान समस्या से जूझ रहा हूं जिसे हम अपनी टीम में लागू कर रहे हैं। हम लीगेसी कोड में इकाई परीक्षणों को जोड़ने का प्रयास कर रहे हैं जो अच्छी तरह से डिज़ाइन नहीं किया गया था और जब तक हम परीक्षण नहीं कर रहे हैं तब तक जिन परीक्षणों के साथ हम संघर्ष शुरू कर रहे हैं उनके वास्तविक जोड़ के साथ हमें कोई कठिनाई नहीं हुई।
समस्या के एक उदाहरण के रूप में मान लें कि आपके पास एक ऐसा तरीका है जो 5 अन्य तरीकों को इसके निष्पादन के हिस्से के रूप में कहता है। इस पद्धति के लिए एक परीक्षण यह पुष्टि करने के लिए हो सकता है कि इन 5 अन्य तरीकों में से एक के परिणामस्वरूप एक व्यवहार होता है। इसलिए, क्योंकि एक इकाई परीक्षण केवल एक कारण और एक कारण के लिए असफल होना चाहिए, आप इन 4 अन्य तरीकों को कॉल करके संभावित समस्याओं को समाप्त करना चाहते हैं और उनका मजाक उड़ाते हैं। महान! यूनिट परीक्षण निष्पादित करता है, नकली तरीकों की अनदेखी की जाती है (और उनके व्यवहार को अन्य यूनिट परीक्षणों के हिस्से के रूप में पुष्टि की जा सकती है), और सत्यापन कार्य करता है।
लेकिन एक नई समस्या है - यूनिट टेस्ट में इस बात की गहन जानकारी है कि आपने उस व्यवहार की पुष्टि कैसे की है और भविष्य में उन 4 तरीकों में से किसी में कोई भी हस्ताक्षर बदल जाता है, या कोई नया तरीका जिसे 'पैरेंट मेथड' में जोड़ना होगा, संभावित विफलताओं से बचने के लिए इकाई परीक्षण को बदलने के परिणामस्वरूप।
स्वाभाविक रूप से समस्या को कुछ हद तक कम किया जा सकता है, बस अधिक विधियाँ कम व्यवहारों को पूरा करती हैं, लेकिन मैं उम्मीद कर रहा था कि शायद अधिक सुरुचिपूर्ण समाधान उपलब्ध था।
यहां एक उदाहरण इकाई परीक्षण है जो समस्या को पकड़ता है।
एक त्वरित नोट के रूप में 'मर्जटेस्ट' एक इकाई परीक्षण वर्ग है जो उस वर्ग से प्राप्त होता है जिसे हम परीक्षण कर रहे हैं और आवश्यकतानुसार व्यवहार को ओवरराइड करते हैं। यह एक 'पैटर्न' है जिसे हम अपने परीक्षणों में नियोजित करते हैं ताकि हम बाहरी वर्गों / निर्भरताओं के कॉल को ओवरराइड कर सकें।
[TestMethod]
public void VerifyMergeStopsSpinner()
{
var mockViewModel = new Mock<MergeTests> { CallBase = true };
var mockMergeInfo = new MergeInfo(Mock.Of<IClaim>(), Mock.Of<IClaim>(), It.IsAny<bool>());
mockViewModel.Setup(m => m.ClaimView).Returns(Mock.Of<IClaimView>);
mockViewModel.Setup(
m =>
m.TryMergeClaims(It.IsAny<Func<bool>>(), It.IsAny<IClaim>(), It.IsAny<IClaim>(), It.IsAny<bool>(),
It.IsAny<bool>()));
mockViewModel.Setup(m => m.GetSourceClaimAndTargetClaimByMergeState(It.IsAny<MergeState>())).Returns(mockMergeInfo);
mockViewModel.Setup(m => m.SwitchToOverviewTab());
mockViewModel.Setup(m => m.IncrementSaveRequiredNotification());
mockViewModel.Setup(m => m.OnValidateAndSaveAll(It.IsAny<object>()));
mockViewModel.Setup(m => m.ProcessPendingActions(It.IsAny<string>()));
mockViewModel.Object.OnMerge(It.IsAny<MergeState>());
mockViewModel.Verify(mvm => mvm.StopSpinner(), Times.Once());
}
आपने बाकी लोगों को इससे कैसे निपटा है या इसे संभालने का कोई बड़ा 'सरल' तरीका नहीं है?
अपडेट - मैं सभी के फीडबैक की सराहना करता हूं। दुर्भाग्य से, और यह वास्तव में कोई आश्चर्य की बात नहीं है, एक महान समाधान, पैटर्न, या अभ्यास नहीं लगता है कि यूनिट परीक्षण में एक का पालन किया जा सकता है यदि परीक्षण किया जा रहा कोड खराब है। मैंने उस उत्तर को चिह्नित किया जिसने इस सरल सत्य को सर्वश्रेष्ठ रूप से कैप्चर किया।