2009-04-23 12 views
17

मैं अपने यूनिट परीक्षणों के लिए नियंत्रक कॉन्टेक्स्ट ऑब्जेक्ट पर कैशिंग ऑब्जेक्ट का नकल कैसे करूं? मैंने किसी भी भाग्य के साथ एक रैपर वर्ग बनाने की कोशिश की है (क्योंकि कैश ऑब्जेक्ट एक सीलबंद वर्ग है)।आप asp.net mvc में कैशिंग ऑब्जेक्ट का नकल कैसे करते हैं?

var mockControllerContext = new Mock<ControllerContext>(); 
var mockhttpContext = new Mock<HttpContextBase>();    

mockhttpContext.SetupGet(o => o.Cache).Returns(
     new CacheWrapper(mockControllerContext.Object.HttpContext.Cache)); 

mockControllerContext.SetupGet(
          o => o.HttpContext).Returns(mockhttpContext.Object); 
this.tennisMatchupController.ControllerContext = mockControllerContext.Object; 

उत्तर

20

संपादित: मैं कम से कम जब आप एक खाली कैश के साथ परीक्षण कर रहे हैं यह करने के लिए एक आसान रास्ता मिल गया। HttpRunTime.Cache का उपयोग HttpContext की कैश प्रॉपर्टी पर आपकी अपेक्षा के लिए वापसी मान के रूप में करें। अधिक उन्नत परिदृश्यों के लिए, एक रैपर और मॉकिंग का उपयोग करना अभी भी इसे संभालने का एक बेहतर तरीका हो सकता है - उदाहरण के लिए, यदि आपको कैश से अपवादों का परीक्षण करने की आवश्यकता है।

var httpContext = MockRepository.GenerateMock<HttpContextBase>(); 
httpContext.Expect(h => h.Cache).Return(HttpRunTime.Cache).Repeat.Any() 

मूल:

आवरण वर्ग जाने का रास्ता है, लेकिन मुझे लगता है कि आप इसे गलत जगह पर आवेदन कर रहे हैं। मैं अपने नियंत्रक को कैशवापर संपत्ति दूंगा, फिर एक कन्स्ट्रक्टर बनाएं जो मुझे कैशवैपर उदाहरण में पास करने की अनुमति देता है जिस पर यह संपत्ति सेट की जा सकती है। डिफ़ॉल्ट रूप से नियंत्रक HttpContext.Current.Cache का उपयोग कर कैशवापर बनाता है। अपने टेस्ट कोड में, नियंत्रक के कन्स्ट्रक्टर में पास करने के लिए एक नकली कैशवापर का निर्माण करें। इस तरह आपको नकली कैश ऑब्जेक्ट बनाने की ज़रूरत नहीं है - जो मुश्किल है क्योंकि यह एक सीलबंद वर्ग है।

वैकल्पिक रूप से, आप केवल कैश क्लास के उदाहरण को तुरंत चालू कर सकते हैं और इसे वापस कर सकते हैं, क्योंकि इसके लिए एक सार्वजनिक निर्माता है। नकली का उपयोग करने का लाभ यह है कि आप यह सत्यापित कर सकते हैं कि कैश का उपयोग अपेक्षाओं के माध्यम से किया जा रहा है, इसलिए, शायद मैं रैपर के साथ जाऊंगा।

public class CacheWrapper 
{ 
    private Cache Cache { get; set; } 

    public CacheWrapper() 
    { 
    this.Cache = HttpContext.Current.Cache; 
    } 

    public virtual Object Add(string key, 
          Object value, 
          CacheDependency dependencies, 
          DateTime absoluteExpiration, 
          TimeSpan slidingExpiration, 
          CacheItemPriority priority, 
          CacheItemRemovedCallback onRemoveCallback) 
    { 
    this.Cache.Add(key, 
        value, 
        dependencies, 
        absoluteExpiration, 
        slidingExpiration, 
        priority, 
        onRemoveCallback); 
    } 

    ...wrap other methods... 
} 


public class BaseController : Controller 
{ 
    private CacheWrapper { get; set; } 

    public BaseController() : this(null) { } 

    public BaseController(CacheWrapper cache) 
    { 
     this.CacheWrapper = cache ?? new CacheWrapper(); 
    } 
} 

[TestMethod] 
public void CacheTest() 
{ 
    var wrapper = MockRepository.GenerateMock<CacheWrapper>(); 

    wrapper.Expect(o => o.Add(...)).Return(...); 

    var controller = new BaseController(wrapper); 

    var result = controller.MyAction() as ViewResult; 

    Assert.AreEqual(...); 

    wrapper.VerifyAllExpectations(); 
} 
0

आप Typemock Isolator उपयोग करने के लिए कोशिश कर सकते हैं, यह बॉक्स से बाहर वर्गों सील जाली, तो आप इन रैपर जरूरत नहीं होगी।

5
HttpContext.Current = new HttpContext(new HttpRequest(null, "http://tempuri.org", null), new HttpResponse(null)); 
11

मैं माइक्रोसॉफ्ट के नए MemoryCache.Default दृष्टिकोण का उपयोग कर की सिफारिश करेंगे। आपको .NET Framework 4.0 या बाद में उपयोग करने की आवश्यकता होगी और सिस्टम का संदर्भ शामिल करें। रनटाइम। कैशिंग

यहाँ लेख देखें ->http://msdn.microsoft.com/en-us/library/dd997357(v=vs.100).aspx

MemoryCache.Default दोनों वेब और गैर वेब अनुप्रयोगों के लिए काम करता है। तो विचार है कि आप HttpContext.Current.Cache के संदर्भों को हटाने के लिए अपने वेबएप को अपडेट करते हैं और उन्हें MemoryCache.Default के संदर्भों के साथ प्रतिस्थापित करते हैं। बाद में, जब आप इन विधियों को यूनिट टेस्ट करने का निर्णय लेते हैं, तो कैश ऑब्जेक्ट अभी भी उपलब्ध है और शून्य नहीं होगा। (क्योंकि यह एक HttpContext पर निर्भर नहीं है।)

इस तरह आपको कैश घटक को नकल करने की भी आवश्यकता नहीं है।

+1

ग्रेट नोट ने वास्तव में पूरी प्रक्रिया को सरल बनाने में मदद की – P6345uk

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