2015-07-10 5 views
20

मैं परीक्षण उद्देश्यों के लिए एक नकली डीबीसेट स्थापित करने की कोशिश कर रहा हूं। मैंने यहां ट्यूटोरियल का इस्तेमाल किया, http://www.loganfranken.com/blog/517/mocking-dbset-queries-in-ef6/ और इसे थोड़ा संशोधित किया ताकि कॉल करने के लिए GetEnumerator प्रत्येक बार एक नया गणक लौटाता है (एक और समस्या जो मैं कर रहा था)। हालांकि, मुझे डीबीसेट में आइटम जोड़ने में कठिनाई हो रही है।किसी मॉक डीबीसेट (एमओक का उपयोग करके) में कोई आइटम कैसे जोड़ें

आउटपुट प्रीकाउंट = 3 पोस्टकाउंट = 3. है, हालांकि, मुझे उम्मीद है कि यह सटीक = 3 पोस्टकाउंट = 4. किसी भी मदद की सराहना की जाएगी।

static void Main(string[] args) 
    { 
     Debug.WriteLine("hello debug"); 

     List<string> stringList = new List<string> 
     { 
      "a", "b", "c" 
     }; 

     DbSet<string> myDbSet = GetQueryableMockDbSet(stringList); 
     int preCount = myDbSet.Count(); 
     myDbSet.Add("d"); 
     int postCount = myDbSet.Count(); 
     Debug.WriteLine("preCount = " + preCount + " postCount = " + postCount); 
    } 

    private static DbSet<T> GetQueryableMockDbSet<T>(List<T> sourceList) where T : class 
    { 
     var queryable = sourceList.AsQueryable(); 

     var dbSet = new Mock<DbSet<T>>(); 
     dbSet.As<IQueryable<T>>().Setup(m => m.Provider).Returns(queryable.Provider); 
     dbSet.As<IQueryable<T>>().Setup(m => m.Expression).Returns(queryable.Expression); 
     dbSet.As<IQueryable<T>>().Setup(m => m.ElementType).Returns(queryable.ElementType); 
     dbSet.As<IQueryable<T>>().Setup(m => m.GetEnumerator()).Returns(() => queryable.GetEnumerator()); 

     return dbSet.Object; 
    } 
+0

बहुत अच्छा विधि dbSet बनाने संपुटित करने के लिए। एसिंक क्वेरी का समर्थन करने के लिए आपने इसे अपडेट किया है? –

+0

कम से कम इस समय के लिए .NET कोर 1.0 के साथ, एसिंक समस्या का उत्तर देगा: [एंटीटी फ्रेमवर्क कोर के साथ एसिंक रेपॉजिटरी को कैसे नकल करें] (https://stackoverflow.com/questions/40476233/how-to-mock -an-async-repository-with-entity-framework-core) –

उत्तर

53

myDbSetDbSet के वास्तविक कार्यान्वयन लेकिन एक नकली जो यह नकली है और यह सभी तरीकों की जरूरत के लिए सेटअप की जरूरत का मतलब नहीं है। Add अपवाद नहीं है, इसलिए आपको जो कुछ चाहिए उसे करने के लिए इसे स्थापित करने की आवश्यकता है अन्यथा यह कुछ भी नहीं करता है।

निम्न जैसे कुछ जोड़ें और जब myDbSet.Add("d"); कहा जाता है तो 'डी' सूची में जोड़ा जाता है और बाद में वापस किया जा सकता है।

dbSet.Setup(d => d.Add(It.IsAny<T>())).Callback<T>((s) => sourceList.Add(s)); 

पूरा कोड

private static DbSet<T> GetQueryableMockDbSet<T>(List<T> sourceList) where T : class 
{ 
    var queryable = sourceList.AsQueryable(); 

    var dbSet = new Mock<DbSet<T>>(); 
    dbSet.As<IQueryable<T>>().Setup(m => m.Provider).Returns(queryable.Provider); 
    dbSet.As<IQueryable<T>>().Setup(m => m.Expression).Returns(queryable.Expression); 
    dbSet.As<IQueryable<T>>().Setup(m => m.ElementType).Returns(queryable.ElementType); 
    dbSet.As<IQueryable<T>>().Setup(m => m.GetEnumerator()).Returns(() => queryable.GetEnumerator()); 
    dbSet.Setup(d => d.Add(It.IsAny<T>())).Callback<T>((s) => sourceList.Add(s)); 

    return dbSet.Object; 
} 

आउटपुट

hello debug 
preCount = 3 postCount = 4 
+0

समस्या यह है कि जब आप डेटाबेस में कुछ जोड़ते हैं तो आपको नेविगेशन गुण मैन्युअल रूप से सेट करना होगा, जबकि यह मॉकिंग ऑब्जेक्ट को इस तरह से सहेज लेगा। मुझे आश्चर्य है कि इस बारे में ईएफ के व्यवहार को अनुकरण करने का एक तरीका है। – tocqueville

+2

मॉकिंग ईएफ का मुद्दा यह है क्योंकि यह आपके परीक्षणों में डेटाबेस लाने की वांछित नहीं है। तेजी से चलने वाले, विभाजित परीक्षणों के लिए बेहतर है जो केवल एक विशिष्ट एपीआई का परीक्षण करते हैं। एक और विकल्प एक https://msdn.microsoft.com/en-us/data/dn314431.aspx "इन-मेमोरी डबल" है, हालांकि, मेमोरी डबल्स और मॉकिंग अनिवार्य रूप से वही बात है। – andrew

+0

एसिंक क्वेरी का समर्थन करने के लिए आपने इसे अपडेट किया है? –

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

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