5

शुरू करने के लिए टॉपशेल्फ़ के साथ एकीकरण टेस्ट मैं सी # में लिखी गई विंडोज सेवा होस्ट करने के लिए Topshelf का उपयोग कर रहा हूं और अब मैं कुछ एकीकरण परीक्षण लिखना चाहता हूं। मेरे initialisation कोड निम्नलिखित की तरह एक लांचर कक्षा में आयोजित किया जाता है:सी # विंडोज सेवा

public class Launcher 
{ 
    private Host host; 

    /// <summary> 
    /// Configure and launch the windows service 
    /// </summary> 
    public void Launch() 
    { 
     //Setup log4net from config file 
     log4net.Config.XmlConfigurator.ConfigureAndWatch(new FileInfo(DEFAULT_CONFIG)); 

     //Setup Ninject dependency injection 
     IKernel kernel = new StandardKernel(new MyModule()); 

     this.host = HostFactory.New(x => 
     { 
      x.SetServiceName("MyService"); 
      x.SetDisplayName("MyService"); 
      x.SetDescription("MyService"); 

      x.RunAsLocalSystem(); 
      x.StartAutomatically(); 

      x.Service<MyWinService>(s => 
      { 
       s.ConstructUsing(() => kernel.Get<MyWinService>()); 
       s.WhenStarted(w => w.Start()); 
       s.WhenStopped(w => w.Stop()); 
      }); 
     }); 

     this.host.Run(); //code blocks here 
    } 

    /// <summary> 
    /// Dispose the service host 
    /// </summary> 
    public void Dispose() 
    { 
     if (this.host != null && this.host is IDisposable) 
     { 
      (this.host as IDisposable).Dispose(); 
      this.host = null; 
     } 
    } 
} 

मुझे यकीन है कि log4net और Ninject ठीक तरह से स्थापित हो बनाने के लिए कुछ एकीकरण परीक्षणों लिखना चाहते हैं और Topshelf मेरी सेवा की शुरूआत। समस्या यह है कि, जब आप TopShelf होस्ट पर Run() पर कॉल करते हैं, तो कोड बस ब्लॉक करता है, इसलिए मेरा टेस्ट कोड कभी नहीं चलाया जाता है।

मैं अपने परीक्षणों के SetUp खंड में एक अलग थ्रेड में Launch() बुला के बारे में सोचा लेकिन फिर मैं एक हैक का एक सा एक Thread.Sleep(1000) में डाल करने के लिए सुनिश्चित करने से पहले Launch() समाप्त हो गया है परीक्षण समाप्त न हो की जरूरत है। मैं इस पर एक उचित सिंक का उपयोग नहीं कर सकता (जैसे ManualResetEvent) क्योंकि Launch() कभी वापस नहीं आता है। वर्तमान कोड है:

private Launcher launcher; 
private Thread launchThread; 

[TestFixtureSetUp] 
public void SetUp() 
{ 
    launcher = new Launcher(); 
    launchThread = new Thread(o => launcher.Launch()); 
    launchThread.Start(); 
    Thread.Sleep(2500); //yuck!! 
} 

[TestFixtureTearDown] 
public void TearDown() 
{ 
    if (launcher != null) 
    { 
     launcher.Dispose(); //ouch 
    } 
} 

आदर्श रूप में मैं क्या तलाश कर रहा हूँ सेवा और इसे फिर से रोक मेरी TearDown में डालने के लिए की एक कार्यक्रम संबंधी तरीका शुरू करने का एक गैर अवरुद्ध तरीका है। फिलहाल मेरे TearDown बस लॉन्चर का निपटान करता है (इसलिए TearDown सचमुच इसे नीचे आँसू देता है!)।

क्या किसी को इस तरह से टॉपशेल्फ़ सेवाओं का परीक्षण करने में अनुभव है? मैं मानक ServiceHost का उपयोग कर उपरोक्त अपेक्षाकृत आसानी से कर सकता हूं लेकिन मैं टॉपशेल्फ़ में स्पष्ट कॉन्फ़िगरेशन और इंस्टॉलेशन की आसानी को अधिक पसंद करता हूं।

उत्तर

2

https://github.com/Topshelf/Topshelf/blob/v2.3/src/Topshelf/Config/Builders/RunBuilder.cs#L113 मुझे लगता है कि आप क्या चाहते हैं। AfterStartingService का उपयोग ManualResetEvent को एक अलग थ्रेड से सेट करने के लिए किया जा सकता है।

अब यह आपके लिए काम कर सकता है, लेकिन यह अत्यधिक जटिल लगता है और इसे केवल dev/staging पर तैनाती करके और आपके सिस्टम में धूम्रपान परीक्षण करके मान्य किया जा सकता है। हालांकि, आपके पर्यावरण की अधिक समझ के बिना, यह संभव नहीं हो सकता है।

+3

में यह निपटाने लिंक – SteveC

+0

टूट गया है @ स्टीवसी अब और नहीं। इस समय लिंक सुलभ है। – dotnetguy

0

आज मेरे पास एक ही समस्या थी और मैंने वास्तविक टॉपशेल्फ़ होस्टिंग से सेवा निष्कासन और बातचीत को अलग करना चुना (जिसमें आपके मामले में निनजेक्ट का उपयोग करके आपकी सेवा को हल करने के अलावा कुछ और नहीं है)।

एडम रॉजर का एक उचित बिंदु है और ConsoleRunHost के लिए रन विधि को तुरंत देखने के बाद, यह वास्तव में ManualResetEvent के लिए प्रतीक्षा करने के लिए लटका होगा और सेवा समाप्त होने तक आपको नियंत्रण वापस नहीं देगा।

अपनी जगह में, अपने धूम्रपान/प्रतिगमन परीक्षण कोड करने के लिए, बस गिरी और अपने SetUp विधि में मॉड्यूल मिलता है, सेवा को हल, अपने परीक्षण करते हैं और TearDown

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

  • कोई संबंधित समस्या नहीं^_^