2012-04-13 24 views
6

मैं MSTest का उपयोग कर रहा MySQL कनेक्टर के माध्यम से एक MySQL 5.5.19 डीबी के खिलाफ कुछ स्वचालित परीक्षण चलाने के लिए और EntityFramework 4.3 का उपयोग करने में विफल रहता है।नेस्टेड TransactionScope परीक्षण

मैं अपने डीबी तक पहुँचने वर्ग पुस्तकालय में TransactionScope उपयोग करने के लिए जब जरूरत एक रोलबैक प्रदर्शन करने के लिए प्रयास कर रहा हूँ। इसके अतिरिक्त, मेरे टेस्ट कोड में मैं TransactionScope का उपयोग प्रत्येक परीक्षण से पहले डीबी को एक ज्ञात राज्य में वापस रखने के लिए करना चाहता हूं। मैं इसे पूरा करने के लिए TestInitialize और TestCleanup विधियों का उपयोग करता हूं। उन इसलिए की तरह लग रहे:

[TestInitialize()] 
public void MyTestInitialize() 
{ 
    testTransScope = new TransactionScope(TransactionScopeOption.RequiresNew); 
} 

[TestCleanup()] 
public void MyTestCleanup() 
{ 
    Transaction.Current.Rollback(); 
    testTransScope.Dispose(); 
} 

TransactionScope इनिशियलाइज़ समारोह में वहाँ वस्तु के निर्माण के आधार पर, मेरा मानना ​​है कि मैं एक नई लेन-देन गुंजाइश (एक "परिवेश" एक तो मौजूदा मैं विश्वास नहीं है हो रही किया जाना चाहिए यह ".RequiresNew" तकनीकी रूप से महत्वपूर्ण नहीं है क्योंकि "आवश्यक" एक ही परिणाम उत्पन्न करेगा। चूंकि मैं टाइमआउट मान निर्दिष्ट नहीं करता हूं, यह मुझे डिफ़ॉल्ट टाइमआउट प्रदान करता है, जिसे मैं 60 सेकंड समझता हूं। ।

: मेरे दिए गए परीक्षण चलाने के लिए समय

मैं एक समारोह AddDessert(DessertBiz dessertBizObject) कहा जाता है जो, लग रहा है हिस्से में, कुछ इस तरह मिल गया है

using (var transScope = new TransactionScope(TransactionScopeOption.Required)) 
{ 
    try 
    { 
     // ... 
     context.Desserts.Add(dessert); 
     context.SaveChanges(); 
     var dessertId = dessert.Id; 
     DoOtherDessertStuff(dessertId, dessertBizObject); 
     transScope.Complete(); 
    } 
    catch (InvalidOperationException ex) 
    { 
     Console.WriteLine(ex.ToString()); 
    } 
} 

और यह फ़ंक्शन मेरे परीक्षणों में से एक द्वारा बुलाया जाता है।

चूंकि मैंने TransactionScopeOption.Required निर्दिष्ट किया है, इसलिए मुझे उम्मीद है कि यह MyTestInitialize फ़ंक्शन द्वारा बनाए गए "परिवेश" लेन-देन के दायरे का उपयोग करेगा।

मेरा परीक्षण असफल और एक अपवाद फेंक करने के लिए इस DoOtherDessertStuff समारोह बनाने के लिए व्यवस्था की है, इसलिए transScope.Complete(); करने के लिए कॉल नहीं होता है और जब AddDessert समारोह में using ब्लॉक बाहर निकलने रोलबैक हो जाती हैं।

समस्या मैं यहाँ है, क्योंकि यह MyTestInitialize समारोह में बनाया परिवेश लेनदेन गुंजाइश, का उपयोग करता है अपने परीक्षण Assert कॉल नहीं होता है क्योंकि लेनदेन गुंजाइश रोलबैक हुआ है - कम से कम इस मैं क्या सोचता हो रहा है। मैंने सत्यापित किया कि Transaction.Current.TransactionInformation.Statusट्रांज़ेक्शनस्टैटस है।, इसलिए मुझे पूरा यकीन है कि यह हो रहा है।

बढ़िया है, इसलिए मैंने सोचा कि मैं अपने AddDesert विधि बदल जाएगा कि मैं घोंसला एक सौदे गुंजाइश बजाय परिवेश से एक का उपयोग होगा छोड़कर बिल्कुल के रूप में ऊपर देखने के लिए, कुछ मेरी using लाइन इस तरह दिखता है दिखता है:

using (var transScope = new TransactionScope(TransactionScopeOption.RequiresNew)) 

यहां का इरादा यह था कि मैं इन लेन-देन के क्षेत्रों को घोंसला कर सकता हूं, मेरे उत्पादन कोड में रोलबैक होने दें और फिर भी मेरे टेस्ट कोड में Assert एस जांचें।

लेकिन क्या मैं लग रहा है कि मैं निम्नलिखित त्रुटि मिलती है:

System.IO.IOException: एक कनेक्शन का प्रयास विफल रहा क्योंकि कनेक्ट किए गए पक्ष ठीक से करने के बाद कोई जवाब नहीं दिया: परिवहन कनेक्शन से डेटा पढ़ने में असमर्थ समय की अवधि, या स्थापित कनेक्शन विफल रहा क्योंकि कनेक्टेड होस्ट जवाब देने में विफल रहा।

विचार?

+0

स्टैकट्रेस और कोड जहां ऐसा होता है पोस्ट करें। – usr

उत्तर

0

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

टेस्ट विधि:

[TestMethod()] 
    public void CreateTestCheckContextCorrectly() 
    { 
     MailJobController target = new MailJobController(); 

     target.AddDessert("dessert for Omer"); 
     //With suppress, even if you rollback ambient trans, suppress will ignore ambient trans. You need to reference new context, previous context from controller may be disposed. 
     using (var suppressscope = new TransactionScope(TransactionScopeOption.Suppress)) 
     { 
      var newdbcontextref = new DbEntities(); 

      int recordcount = newdbcontextref.StatusDefinitions.Where(x => x.Name == "dessert for Omer").Count(); 

      Assert.AreEqual(0, recordcount); 
     } 
    } 

नियंत्रक विधि:

public void AddDessert(string dessert) 
    { 
     using (var transScope = new TransactionScope()) 
     { 
      try 
      { 
       // ... 
       StatusDefinition statusDefinition = new StatusDefinition() {Name = dessert}; 
       db.StatusDefinitions.AddObject(statusDefinition); 
       db.SaveChanges(); 
       Console.WriteLine("object id:"+statusDefinition.StatusDefinitionId); 
       throw new Exception("hee hee"); 
       transScope.Complete(); 
      } 
      catch (Exception ex) 
      { 
       Console.WriteLine(ex.ToString()); 
      } 
     } 
    }