2009-07-13 12 views
5

से बाहर निकलती है मैं वीएस 2008 के अंतर्निर्मित इकाई परीक्षण ढांचे के साथ एक सी # इकाई परीक्षण लिखने की कोशिश कर रहा हूं और जिस विधि का मैं परीक्षण कर रहा हूं Environment.Exit(0)। जब मैं इस विधि को अपने यूनिट टेस्ट में कॉल करता हूं, तो मेरा यूनिट परीक्षण निरस्त हो जाता है। विधि वास्तव में Exit पर कॉल करनी चाहिए, और मैं यह जांचने का एक तरीका चाहता हूं कि यह करता है, और इसका उपयोग करने वाले निकास कोड का परीक्षण भी करना है। मैं यह कैसे कर सकता हूं? मैंने Microsoft.VisualStudio.TestTools.UnitTesting Namespace देखा लेकिन प्रासंगिक कुछ भी दिखाई नहीं दिया।वीएस -2008 यूनिट परीक्षण - जोर विधि

[TestMethod] 
[DeploymentItem("myprog.exe")] 
public void MyProgTest() 
{ 
    // Want to ensure this Exit's with code 0: 
    MyProg_Accessor.myMethod(); 
} 

इस बीच, यहाँ कोड का सार है कि मैं परीक्षण करना चाहते हैं:

static void myMethod() 
{ 
    Environment.Exit(0); 
} 

संपादित करें:

Process proc; 

try 
{ 
    proc = Process.Start(path, myArgs); 
} 
catch (System.ComponentModel.Win32Exception ex) 
{ 
    proc = null; 
    Assert.Fail(ex.Message); 
} 

Assert.IsNotNull(proc); 
proc.WaitForExit(10000); 
Assert.IsTrue(proc.HasExited); 
Assert.AreEqual(code, proc.ExitCode); 
:
यहाँ समाधान मैं अपने परीक्षण विधि में प्रयोग किया जाता है, धन्यवाद RichardOD करने के लिए

उत्तर

4

यह एक अविश्वसनीय रूप से बुरा विचार की तरह लगता है। पर्यावरण। एक्सिट (0), स्पष्ट रूप से निर्धारित के रूप में करेंगे, इसलिए आपकी इकाई परीक्षण क्यों टूट रहे हैं।

यदि आप वास्तव में अभी भी परीक्षण करना चाहते हैं तो आप एक अलग प्रक्रिया लॉन्च करके और रिटर्न कोड की जांच करके कर सकते हैं- Process.Start में इसे लपेटने पर एक नज़र डालें।

मुझे लगता है कि एक और विकल्प इस कोड को फैक्टर कर रहा है और test spy इंजेक्शन कर रहा है, या सही व्यवहार को सत्यापित करने के लिए नकली ऑब्जेक्ट का उपयोग कर रहा है।

शायद आप Typemock Isolator के साथ कुछ कर सकते हैं- मुझे विश्वास है कि यह आपको mock static methods देता है।

+0

TypeMock अलगाने पर +1 यहाँ - यह एकमात्र समाधान मैं जो की मदद से आप रोकना और बिल्कुल कुछ भी नकली के बारे में पता कर रहा हूँ है। –

+0

स्थैतिक तरीकों का नकल करने में सक्षम होने का खतरा यह है कि आप उन्हें आसानी से उपयोग करने से नहीं रोकते हैं। मुझे वास्तव में लगता है कि (मेरे कोड के लिए) स्थिर विधियों के लिए अतिरिक्त कड़ी मेहनत करने के लिए मजबूर होना एक अच्छी बात है क्योंकि मैं उनका उपयोग नहीं करूँगा जब तक वे पूर्णत: सर्वोत्तम समाधान नहीं होते। इससे बेहतर तकनीक, आईएमओ का उपयोग करके विकास को मजबूर करने में मदद मिलती है। नकारात्मकता यह है कि जब आप समझ में आते हैं तो उन स्थिर तरीकों से बातचीत करते समय आपको हुप्स के माध्यम से कूदने के लिए मजबूर किया जाता है (या ढांचे को परीक्षण में बनाया गया है)। – tvanfosson

+0

@ tvanfosson- यह एक अच्छा मुद्दा है। यही कारण है कि कई लोग (स्वयं शामिल) टेस्टेबल कोड लिखते समय स्थिर तरीकों का उपयोग करने से बचने का प्रयास करते हैं। स्थिर रूप से .NET फ्रेमवर्क कक्षाएं एक दर्द परीक्षण हैं और डेवलपर्स को इसे टेस्ट करने योग्य बनाने के लिए अक्सर लेखन रैपर कोड का सहारा लेना पड़ता है (आपके उत्तर के अनुसार)। आप एएसपी.नेट वेब फॉर्म के एएसपी.नेट एमवीसी के विकास से इसे बहुत कुछ देख सकते हैं। – RichardOD

3

आप इसका परीक्षण करने में सक्षम नहीं होंगे - Environment.Exit एप्लिकेशन को पूरी तरह मार देता है। इसका अर्थ यह है कि इस कोड का उपयोग करने वाले किसी भी ऐपडोमेन को पूरी तरह से अनलोड किया जाएगा, भले ही यह आपका उत्पादन एप्लिकेशन या इकाई परीक्षण ढांचा है।

2

आपका एकमात्र विकल्प यहां पर्यावरण वर्ग को एक फकी एक्जिट विधि के साथ नकल करना होगा।

5

आपको पर्यावरण वर्ग के लिए एक रैपर बनाने की आवश्यकता होगी, फिर अपने कोड में रैपर का उपयोग करें। अपने यूनिट परीक्षणों के लिए, रैपर के नकली संस्करण को इंजेक्ट करें। निम्न उदाहरण राइनोमोक्स का उपयोग यह सत्यापित करने के लिए करता है कि विधि रैपर को अपेक्षित तर्क के साथ कॉल करती है।

public class EnvironmentWrapper 
{ 
    public virtual void Exit(int code) 
    { 
     Environment.Exit(code); 
    } 
} 


public class MyClass 
{ 
    private EnvironmentWrapper Environment { get; set; } 

    public MyClass() : this(null) { } 

    public MyClass(EnvironmentWrapper wrapper) 
    { 
     this.Environment = wrapper ?? new EnvironmentWrapper(); 
    } 

    public void MyMethod(int code) 
    { 
     this.Environment.Exit(code) 
    } 
} 


[TestMethod] 
public void MyMethodTest() 
{ 
    var mockWrapper = MockRepository.GenerateMock<EnvironmentWrapper>(); 

    int expectedCode = 5; 

    mockWrapper.Expect(m => m.Exit(expectedCode)); 

    var myClass = new MyClass(mockWrapper); 

    myclass.MyMethod(expectedCode); 

    mockWrapper.VerifyAllExpectations() 
} 
+1

+1। अच्छा उदाहरण, अगर मैं अपना रात का खाना नहीं खा रहा था तो मैं उन पंक्तियों के साथ कुछ कोड करने जा रहा था! आपका कोड मुझे एएसपी.नेट एमवीसी परियोजनाओं में डिफ़ॉल्ट कोड की याद दिलाता है खाता नियंत्रक वर्ग- जो केवल एक अच्छी बात हो सकती है। व्यक्तिगत रूप से मैं सार्वजनिक पर्यावरणप्रकाश पर्यावरण बदलूंगा {प्राप्त करें; सेट; } एक निजी सेट के लिए, लेकिन उस अच्छे उदाहरण के अलावा। – RichardOD

+0

@ रिचर्डोड - जनता/निजी पर सहमत हुए। अपडेट करूंगी। – tvanfosson

0

आप इसे एक नकली वातावरण पारित करने के लिए अपने विधि के लिए एक तर्क जोड़ सकते हैं जहां से बाहर निकलें() विधि से बाहर निकलने नहीं होगा।

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

0

केवल एक चीज है कि मेरे दिमाग में आता है के साथ कुछ है:

static void myMethod() 
{ 
    DoEnvironmentExit(0); 
} 

static void DoEnvironentExit(int code) 
{ 
    #if defined TEST_SOLUTION 
     SomeMockingFunction(code); 
    #else 
     Environment.Exit(code); 
    #endif 
} 
संबंधित मुद्दे