2016-11-18 25 views
7

परीक्षण का उचित तरीका मैं एक साधारण परीक्षण केस लिख रहा हूं जो परीक्षण करता है कि मेरा नियंत्रक मेरी सेवा को कॉल करने से पहले कैश को कॉल करता है। मैं कार्य के लिए xUnit और Moq का उपयोग कर रहा हूँ।एएसपी.NET कोर IMEMoryCache

मुझे एक समस्या का सामना करना पड़ रहा है क्योंकि GetOrCreateAsync<T> एक विस्तार विधि है, और उनको ढांचे द्वारा नकल नहीं किया जा सकता है। मैं आंतरिक विवरण पर भरोसा किया यह पता लगाने की मैं TryGetValue बजाय नकली और अपने परीक्षण के साथ भाग प्राप्त कर सकते हैं (https://github.com/aspnet/Caching/blob/c432e5827e4505c05ac7ad8ef1e3bc6bf784520b/src/Microsoft.Extensions.Caching.Abstractions/MemoryCacheExtensions.cs#L116 देख)

[Theory, AutoDataMoq] 
public async Task GivenPopulatedCacheDoesntCallService(
    Mock<IMemoryCache> cache, 
    SearchRequestViewModel input, 
    MyViewModel expected) 
{ 
    object expectedOut = expected; 
    cache 
     .Setup(s => s.TryGetValue(input.Serialized(), out expectedOut)) 
     .Returns(true); 
    var sut = new MyController(cache.Object, Mock.Of<ISearchService>()); 
    var actual = await sut.Search(input); 
    Assert.Same(expected, actual); 
} 

मैं तथ्य यह है कि मैं MemoryCache कार्यान्वयन विवरण और यह में देखना कर रहा हूँ के साथ सो नहीं सकता किसी भी बिंदु पर बदल सकते हैं।

public async Task<MyViewModel> Search(SearchRequestViewModel request) 
{ 
    return await cache.GetOrCreateAsync(request.Serialized(), (e) => search.FindAsync(request)); 
} 

आप किसी भी अलग ढंग से जांच करने की अनुशंसा करेंगे:

के लिए, इस SUT कोड है?

+2

आप 'IMemoryCache' का परीक्षण नहीं किया जाना चाहिए क्योंकि यह एक पुस्तकालय का हिस्सा है। पुस्तकालय के लेखकों को परीक्षण करना चाहिए। –

उत्तर

14

ईमानदार होने के लिए मैं इस बातचीत का परीक्षण न करने की सलाह दूंगा।

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

तथ्य यह है कि दृश्यों के पीछे IMemoryCache का उपयोग केवल एक कार्यान्वयन विस्तार है। मैं इसके लिए एक टेस्ट डबल सेट करने की भी परेशानी नहीं करता, मैं बस Microsoft.Extensions.Caching.Memory.MemoryCache ऑब्जेक्ट का एक उदाहरण उपयोग करता हूं।

मेरा नया परीक्षण कुछ इस तरह दिखेगा:

[Theory] 
public async Task GivenResultAlreadyRetrieved_ShouldNotCallServiceAgain() 
{ 
    // Arrange 
    var expected = new MyViewModel(); 
    object actualOut; 

    var cache = new MemoryCache(new MemoryCacheOptions()); 
    var searchService = new Mock<ISearchService>(); 

    var input = new SearchRequestViewModel(); 

    searchService 
     .SetupSequence(s => s.FindAsync(It.IsAny<SearchRequestViewModel>())) 
     .Returns(Task.FromResult(expected)) 
     .Returns(Task.FromResult(new MyViewModel())); 

    var sut = new MyController(cache, searchService.Object); 

    // Act 
    var resultFromFirstCall = await sut.Search(input); 
    var resultFromSecondCall = await sut.Search(input); 

    // Assert 
    Assert.Same(expected, resultFromFirstCall); 
    Assert.Same(expected, resultFromSecondCall); 
} 
+0

मुझे आपके दृष्टिकोण को बहुत पसंद है। धन्यवाद! –