अनाम नाम स्थान कोड को अस्थिर बनाते हैं


12

यहाँ एक विशिष्ट C ++ कोड है:

foo.hpp

#pragma once

class Foo {
public:
  void f();
  void g();
  ...
};

foo.cpp

#include "foo.hpp"

namespace {
    const int kUpperX = 111;
    const int kAlternativeX = 222;

    bool match(int x) {
      return x < kUpperX || x == kAlternativeX;
    }
} // namespace

void Foo::f() {
  ...
  if (match(x)) return;
  ...

यह एक सभ्य मुहावरेदार सी ++ कोड की तरह दिखता है - एक वर्ग, एक सहायक फ़ंक्शन matchजिसका उपयोग Fooउस सहायक फ़ंक्शन के लिए कुछ स्थिरांक के तरीकों से किया जाता है ।

और फिर मैं परीक्षण लिखना चाहता हूं।
यह एक अलग इकाई परीक्षण लिखने के लिए पूरी तरह से तर्कसंगत होगा match, क्योंकि यह काफी गैर-तुच्छ है।
लेकिन यह एक अनाम नाम स्थान पर रहता है।
बेशक मैं एक परीक्षण लिख सकता हूं जो कॉल करेगा Foo::f()। हालांकि यह Fooभारी और जटिल होने पर एक अच्छा परीक्षण नहीं होगा, ऐसा परीक्षण अन्य असंबंधित कारकों से परीक्षार्थी को अलग नहीं करेगा।

इसलिए मुझे आगे बढ़ना है matchऔर बाकी सभी चीजों को अनाम नामस्थान से बाहर ले जाना है ।

प्रश्न: अनाम नामस्थान में फ़ंक्शन और स्थिरांक लगाने की बात क्या है, अगर यह उन्हें परीक्षणों में अनुपयोगी बनाता है?


3
@ B @овиЈ कोड को फिर से पढ़ें - अनाम नाम स्थान में है foo.cpp, हेडर नहीं है! ओपी को अच्छी तरह से समझ में आ रहा है कि आपको एक हेडर में एनोन नामस्थान नहीं डालना चाहिए।
अमोन

यूनिट टेस्टिंग C ++ कोड में कुछ विचार एक Namespace ... पर "बिंदु" है कि एनकैप्सुलेशन अच्छा है। आखिरकार यह वही समस्या है जो आपके पास निजी सदस्य कार्यों के साथ है: उन्हें गैर-कानूनी रूप से परीक्षण नहीं किया जा सकता है, लेकिन आप इकाई परीक्षण (जैसे stackoverflow.com/a/3676680/3235496 ) के लिए जानकारी छुपाना नहीं चाहते हैं ।
manlio

1
आप का मामला वैचारिक रूप से निजी तरीकों के परीक्षण (या परीक्षण नहीं) के मामले से बहुत अलग नहीं है। इसलिए जब आप यहां प्रोग्रामर्स पर "यूनिट टेस्ट प्राइवेट" की खोज करते हैं, तो आपको बहुत सारे उत्तर मिलेंगे जो आप सीधे अपने मामले में आवेदन कर सकते हैं।
डॉक्टर ब्राउन

@DocBrown मैं यह नहीं पूछ रहा हूं कि एनोन में कार्यों का परीक्षण कैसे करें। नामस्थान। मैं पूछ रहा हूँ "कोड को एनोन में क्यों रखा है। नाम स्थान?" (प्रश्न के अंत में पाठ देखें)। शीर्षक को कुछ अलग करने के लिए Ixrec को दोष दें।
अबिक

2
@ एबीएक्स: उन अन्य उत्तरों में, जिनका मैंने ऊपर उल्लेख किया है, आपको यहां कई विशेषज्ञों की एक बड़ी सहमति मिलेगी कि यह निजी तरीकों का परीक्षण करने के लिए एक बहुत बुरा विचार है, और friendउस उद्देश्य के लिए कीवर्ड का दुरुपयोग करने की सिफारिश नहीं की गई है। अपनी धारणा के साथ गर्भपात करें। कि अगर किसी विधि के लिए प्रतिबंध एक ऐसी स्थिति की ओर ले जाता है जहाँ आप इसे सीधे किसी भी अधिक परीक्षण नहीं कर सकते हैं, तो इसका मतलब यह होगा कि निजी तरीके उपयोगी नहीं थे।
डॉक्टर ब्राउन

जवाबों:


7

यदि आप निजी कार्यान्वयन-विवरणों को इकाई-परीक्षण करना चाहते हैं, तो आप निजी या (संरक्षित) वर्ग के सदस्यों के लिए अनाम नामस्थान के लिए एक ही प्रकार का चकमा देते हैं:

में तोड़ो और पार्टी करो।

वर्गों के लिए आप दुरुपयोग करते हैं friend, अनाम नामस्थान के लिए आप #include-mechanism का दुरुपयोग करते हैं , जो आपको कोड बदलने के लिए भी मजबूर नहीं करता है।
अब जबकि आपका टेस्ट-कोड (या हर चीज़ को उजागर करने के लिए बेहतर है) एक ही टीयू में है, कोई समस्या नहीं है।

सावधानी का एक शब्द: यदि आप कार्यान्वयन-विवरणों का परीक्षण करते हैं, तो आपका परीक्षण उन परिवर्तनों को तोड़ देगा। वास्तव में केवल उन कार्यान्वयन-विवरणों का परीक्षण करना सुनिश्चित करें, जो वैसे भी लीक होंगे, या स्वीकार करेंगे कि आपका परीक्षण असामान्य रूप से अल्पकालिक है।


6

आपके उदाहरण में फ़ंक्शन काफी जटिल दिखता है, और यूनिट परीक्षण के उद्देश्य से इसे हेडर में स्थानांतरित करना बेहतर हो सकता है।

अनाम नामस्थान में फ़ंक्शंस और स्थिरांक लगाने का क्या मतलब है, अगर यह उन्हें परीक्षणों में अनुपयोगी बनाता है?

उन्हें बाकी दुनिया से अलग-थलग करने के लिए। और यह केवल फ़ंक्शन और स्थिरांक नहीं है जिसे आप गुमनाम नाम स्थान पर रख सकते हैं - यह प्रकारों के लिए भी है।

हालांकि, अगर यह आपकी इकाई परीक्षणों को बहुत जटिल बनाता है, तो आप इसे गलत कर रहे हैं। ऐसे मामले में फंक्शन वहां नहीं होता है। फिर परीक्षण को सरल बनाने के लिए थोड़ा रिफैक्टिंग करने का समय है।

तो, अनाम नामस्थान में केवल बहुत ही सरल कार्यों को जाना चाहिए, कभी-कभी उस अनुवाद इकाई में उपयोग किए गए स्थिरांक और प्रकार (टाइपडेफ़्स सहित)।


5

मैच के लिए एक अलग इकाई परीक्षण लिखना पूरी तरह से तर्कसंगत होगा, क्योंकि यह काफी गैर-तुच्छ है।

आपके द्वारा दिखाया गया कोड matchबिना किसी ट्रिक एज केस के एक बहुत ही मामूली 1-लाइनर है, या क्या यह एक सरल उदाहरण की तरह है? वैसे भी, मुझे लगता है कि यह सरल होगा ...

प्रश्न: अनाम नामस्थान में फ़ंक्शन और स्थिरांक लगाने की बात क्या है, अगर यह उन्हें परीक्षणों में अनुपयोगी बनाता है?

यह सवाल है कि क्या मुझे यहाँ कूदने के लिए करना चाहता था क्योंकि डेडुप्लिकेटर ने पहले से ही अंदर तोड़ने और #includeप्रवंचना के माध्यम से पहुंचने का एक अच्छा तरीका दिखाया । लेकिन यहां शब्दांकन ऐसा लगता है कि हर एक चीज के आंतरिक कार्यान्वयन के विस्तार का परीक्षण करने पर लगता है कि यह किसी प्रकार का सार्वभौमिक अंतिम लक्ष्य है, जब यह इससे दूर है।

इकाई परीक्षण का लक्ष्य हमेशा कार्यक्षमता की हर छोटी बारीक आंतरिक सूक्ष्म इकाई का परीक्षण करना नहीं होता है। एक ही सवाल पूछकर सी आप में स्थिर फ़ाइल-गुंजाइश कार्यों के लिए लागू होता भी जवाब देने के लिए प्रश्न कठिन बना सकते हैं क्यों डेवलपर्स का उपयोग pimplsC ++ जो आवश्यकता होगी दोनों friendship और #includeप्रवंचना सफेद बॉक्स करने के लिए, बेहतर संकलन समय के लिए कार्यान्वयन विवरण के आसान testability व्यापार, जैसे

एक तरह के व्यावहारिक दृष्टिकोण से, यह सकल लग सकता है लेकिन इसे matchकुछ किनारे वाले मामलों के साथ सही ढंग से लागू नहीं किया जा सकता है जो इसे यात्रा करने का कारण बनता है। हालांकि, अगर एकमात्र बाहरी वर्ग, Foo, की पहुंच न हो matchसंभवतः एक तरह से उपयोग नहीं कर सकते कि मुठभेड़ों उन बढ़त मामलों, तो यह नहीं बल्कि अप्रासंगिक है की शुद्धता के लिए Fooकि matchइन बढ़त मामलों है कि जब तक सामना किया जा कभी नहीं होगा है Fooपरिवर्तन, जो बिंदु पर के परीक्षण Fooविफल हो जाएंगे और हम तुरंत जान जाएंगे।

एक अधिक जुनूनी मानसिकता हर एक आंतरिक कार्यान्वयन विवरण (शायद एक मिशन-महत्वपूर्ण सॉफ़्टवेयर, उदाहरण के लिए) का परीक्षण करने के लिए उत्सुक हो सकता है और पार्टी में टूट सकता है, लेकिन बहुत से लोग जरूरी नहीं समझते कि यह सबसे अच्छा विचार है, क्योंकि यह पैदा करेगा। सबसे भंगुर परीक्षण कल्पना। YMMV। लेकिन मैं सिर्फ इस सवाल के शब्दों को संबोधित करना चाहता था, जो इस तरह की आवाज करता है जैसे कि उबेर-ठीक-दानेदार-आंतरिक-विस्तार-स्तरीय परीक्षण क्षमता एक अंतिम लक्ष्य होना चाहिए, जब यहां तक ​​कि सबसे कठोर इकाई परीक्षण मानसिकता भी थोड़ा आराम कर सकती है और हर वर्ग के आंतरिक मामलों में एक्स-रे करने से बचें।

तो लोग C ++ में अनाम नामस्थानों में या बाहरी दुनिया से छिपे हुए सी में आंतरिक लिंकेज के साथ फ़ाइल-स्कोपिक स्टैटिक फ़ंक्शंस में फ़ंक्शन को क्यों परिभाषित करते हैं? और यह मुख्य रूप से यह है: उन्हें बाहरी दुनिया से छिपाने के लिए। यह जटिलता को कम करने के लिए संकलन समय को कम करने से लेकर (जो अन्यत्र नहीं पहुँचा जा सकता है, कहीं और समस्याएँ पैदा नहीं कर सकता है) और इसके आगे के कई प्रभाव हैं। संभवतः निजी / आंतरिक कार्यान्वयन विवरणों की परीक्षणशीलता लोगों के दिमाग पर नंबर एक चीज नहीं है जब वे इसे करते हैं, कहते हैं, बिल्ड समय को कम करते हैं और बाहरी दुनिया से अनावश्यक जटिलता को छिपाते हैं।


काश, मैं इस दस बार उत्थान कर पाता। मिशन महत्वपूर्ण, उच्च आश्वासन सॉफ्टवेयर से संबंधित एक स्पर्शरेखा के रूप में, आप विवरण की शुद्धता के साथ बहुत अधिक चिंतित हैं। C ++ के लिए यह मुहावरेदार शैली उसके लिए अनुकूल नहीं है। मैं अनाम नेमस्पेस या प्रॉक्सी जैसे पैटर्न की भाषा की विशेषताओं का उपयोग नहीं करूंगा। मैं [समर्थित] उपयोगकर्ता-अंतरिक्ष हेडर और [असमर्थित] डेवलपर अंतरिक्ष हेडर के साथ अपनी सीमा को नियंत्रित करता हूं।
डेविड
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.