2008-12-08 25 views
13

मैं एक ऐसा एप्लिकेशन बना रहा हूं जो बाह्य उपयोगिता के कई उदाहरणों का प्रबंधन करेगा, प्रत्येक डेटा को डेटा और परिणाम लाएगा।परीक्षण प्रक्रिया। स्टार्ट?

लेकिन जैसा कि मैं कक्षा के लिए यूनिट परीक्षण लिख रहा हूं, मैं एक समस्या पर आया था।

परीक्षण विधि वास्तव में एक प्रक्रिया (एक संपत्ति के माध्यम से सेट) शुरू करने का परीक्षण कैसे करती है?

मैं कोशिश की है:

  • वर्ग एक बाहरी प्रक्रिया पर अमल और उसके बाद ही यह शुरू कर दिया है की जाँच करने के GetProcessesByName उपयोग सुनिश्चित करें।
  • आउटपुट रीडायरेक्शन का उपयोग करें, उदा। किसी फ़ाइल में कुछ गूंजने के लिए साइन-इन का उपयोग करके और इसके अस्तित्व का परीक्षण करने के लिए

मुझे लगता है कि कोड उत्सर्जित करना और/या परीक्षण करने के लिए अभी तक एक और exe बनाना ओवरकिल है।

public void Start() 
{ 
    if (!_isRunning) { 
     var startInfo = new ProcessStartInfo() { 
      CreateNoWindow = true, 
      UseShellExecute = true, 

      FileName = _cmdLine, 
      Arguments = _args 
     }; 

     _process = Process.Start(startInfo); 
     _isRunning = true; 

    } else { 
     throw new InvalidOperationException("Process already started"); 

    } 
} 

मैं चाहता हूँ इकाई परीक्षण करने के लिए यह इतना है कि कुछ भी नहीं चल रहा है तो (_isRunning == गलत), एक नई प्रक्रिया पैदा की जानी चाहिए:

यह सही तरीका है।

मुझे लगता है कि स्टंप हो गया है, क्या यूनिट-टेस्ट के लिए एक शानदार तरीका है कि बाहरी प्रक्रिया वास्तव में शुरू होती है?

उत्तर

10

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

public class UtilityManager 
{ 
     public Process UtilityProcess { get; private set; } 

     private bool _isRunning; 

     public UtilityManager() : this(null) {} 

     public UtilityManager(Process process) 
     { 
      this. UtilityProcess = process ?? new Process(); 
      this._isRunning = false; 
     } 

     public void Start() 
     { 
      if (!_isRunning) { 
      var startInfo = new ProcessStartInfo() { 
       CreateNoWindow = true, 
       UseShellExecute = true, 

       FileName = _cmdLine, 
       Arguments = _args 
      }; 

      this.UtilityProcess.Start(startInfo); 
      _isRunning = true; 

     } else { 
      throw new InvalidOperationException("Process already started"); 
     } 
} 
टेस्ट कोड

...

[TestMethod] 
public void StartTest() 
{ 
     Process proc = new FakeProcess(); // May need to use a wrapper class 
     UtilityManager manager = new UtilityManager(proc); 
     manager.CommandLine = "command"; 
     ... 

     manager.Start(); 


     Assert.IsTrue(proc.StartCalled); 
     Assert.IsNotNull(proc.StartInfo); 
     Assert.AreEqual("command", proc.StartInfo.FileName); 
     ... 
} 
+0

अच्छा ... मैं startInfo जुदाई हिस्सा अनदेखी ... कुछ और मजाक के आसपास मेरे सिर प्राप्त करने के लिए ... धन्यवाद दिया है! – chakrit

+0

आप 'सार्वजनिक उपयोगिता प्रबंधक() को बदल सकते हैं: यह (शून्य) {} सार्वजनिक उपयोगिता प्रबंधक (प्रक्रिया प्रक्रिया) 'सार्वजनिक उपयोगिता प्रबंधक (प्रक्रिया प्रक्रिया = शून्य)' के लिए छोटे कोड के लिए। – Bomberlt

+0

@ बॉम्बरलट अगर मैं एक डिफॉल्ट कन्स्ट्रक्टर को उन टूल्स द्वारा उपयोग करने के लिए उपलब्ध नहीं करता जो प्रतिबिंब के माध्यम से इसका उपयोग करते हैं। – tvanfosson

संबंधित मुद्दे