2010-11-14 7 views
7

के साथ stubbed मैं mockito के साथ एक समस्या में भाग गया। मैं एक वेब अनुप्रयोग विकसित कर रहा हूं। मेरे परीक्षणों में उपयोगकर्ता प्रबंधन का मज़ाक उड़ाया जाता है। कुछ ऐसे मामले हैं जब मुझे getLoggedInUser() विधि द्वारा लौटाए गए उपयोगकर्ता को बदलना होगा।मॉकिटो री-स्टब विधि पहले से ही थ्रोथ्रो

समस्या यह है कि मेरी getLoggedInUser() विधि AuthenticationException भी फेंक सकती है।

तो जब मैं कोई उपयोगकर्ता से, करने के लिए

when(userProvider.getLoggedInUser()).thenReturn(user); 

एक अपवाद फेंकता है, कुछ उपयोगकर्ता पर स्विच करने के लिए कॉल के रूप में पहले से ही userProvider.getLoggedInUser()thenTrow()

साथ टोंटदार है की कोशिश वहाँ बताने के लिए कोई तरीका है when विधि अपवादों की परवाह नहीं है?

अग्रिम धन्यवाद - István

+0

उत्तर के लिए धन्यवाद दोस्तों! समेकित करने के लिए: यह संभवतः सॉफ़्टवेयर के खराब डिज़ाइन की वजह से है जिसे मुझे विधि को पुन: स्थापित करने की आवश्यकता है। लेकिन अभी के लिए यह मेरे लिए आसान है, और परीक्षण भी साफ दिखते हैं। मैंने कुछ और शोध किया और Mockito.reset (टी ... mocks) विधि पाई है, जो मेरे लिए चाल है। अगली बार मैं कुछ और सरल डिज़ाइन का पता लगाऊंगा :) – Szobi

उत्तर

2

आपके प्रश्न पर मेरी पहली प्रतिक्रिया यह है कि ऐसा लगता है कि आप एक परीक्षण में बहुत अधिक करने की कोशिश कर रहे हैं।

परीक्षण और सादगी की आसानी के लिए प्रत्येक परीक्षण को केवल एक चीज का परीक्षण करना चाहिए। यह Single Responsibility Principle जैसा ही है। मैं अक्सर प्रोग्रामर को एक परीक्षण में कई चीजों का परीक्षण करने की कोशिश कर रहा हूं और इसके कारण सभी प्रकार की समस्याएं हैं। तो आपके प्रत्येक इकाई परीक्षण विधियों को इस प्रवाह का पालन करना चाहिए:

  1. परीक्षण के लिए एक एकल परिदृश्य सेटअप करें।
  2. परीक्षण किए जा रहे कोड को ट्रिगर करने के लिए कक्षा में कॉल करने के लिए कॉल करें।
  3. व्यवहार की पुष्टि करें।

तो आपके मामले में मुझे कम से कम दो परीक्षण देखने की उम्मीद होगी। एक जहां getLoggedInUser() उपयोगकर्ता को लौटाता है, और एक जहां getLoggedInUser() अपवाद फेंकता है। इस तरह आपको नकली में विभिन्न व्यवहार अनुकरण करने की कोशिश करने में कोई समस्या नहीं होगी।

दूसरा विचार है कि वसंत को ध्यान में रखना नहीं है। इसके बजाय उम्मीद का उपयोग करने में देखो क्योंकि आप उम्मीद की एक श्रृंखला स्थापित कर सकते हैं। अर्थात। पहला कॉल उपयोगकर्ता को लौटाता है, दूसरा कॉल अपवाद फेंकता है, तीसरा कॉल एक अलग उपयोगकर्ता देता है, आदि

+1

'उम्मीद' या दस्तावेज़ीकरण/ट्यूटोरियल के लिंक का एक उदाहरण सराहना की जाएगी :) –

2

ऐसा लगता है आप एक कस्टम जवाब उपयोग करना पड़ सकता है। Here is an example

+0

धन्यवाद javamonkey, यह भी एक उचित समाधान है, लेकिन अभी के लिए मैं Mockito.reset() के साथ रहूंगा। – Szobi

+0

दिलचस्प - मैं आपको सामान्य रूप से रीसेट के बारे में सीखा जानकारी के लिए सामान्य रूप से प्रश्न पर +1 दूंगा। मुझे यकीन है कि आप इसे भी पढ़ते हैं, इसलिए मैं इसे दोहराना नहीं चाहूंगा ... अच्छी चीजें :) – javamonkey79

+0

+1 के लिए धन्यवाद :) – Szobi

9

नए मॉकिटो संस्करणों में आप पहले कॉल पर अपवाद फेंकने और एक मूल्य वापस करने के लिए निरंतर कॉल को दबा सकते हैं दूसरी कॉल

when(mock.someMethod("some arg")) 
    .thenThrow(new RuntimeException()) 
    .thenReturn("foo"); 

http://docs.mockito.googlecode.com/hg/latest/org/mockito/Mockito.html#stubbing_consecutive_calls

1

वहाँ जब विधि अपवाद के बारे में परवाह नहीं बताने के लिए कोई तरीका है? ज़ोर कि आप में से छुटकारा नहीं मिल रहा की वजह से

import static org.hamcrest.Matchers.equalTo; 
import static org.hamcrest.Matchers.is; 
import static org.junit.Assert.assertThat; 
import static org.mockito.ArgumentMatchers.any; 
import static org.powermock.api.mockito.PowerMockito.mock; 
import static org.powermock.api.mockito.PowerMockito.when; 

import org.junit.Test; 
import org.mockito.Mockito; 

import java.util.ArrayList; 

public class MyTest { 

    @Test 
    public void testA() { 

     // setup 
     ArrayList<Object> list = mock(ObjectArrayList.class); 
     when(list.indexOf(any())).thenReturn(6); 
     when(list.indexOf(any())).thenReturn(12); 

     // execute 
     int index = list.indexOf(new Object()); 

     // verify 
     assertThat(index, is(equalTo(12))); 
    } 

    @Test 
    public void testB() { 

     // setup 
     ArrayList<Object> list = mock(ObjectArrayList.class); 
     when(list.add(any())).thenThrow(new AssertionError("can't get rid of me!")); 
     when(list.add(any())).thenReturn(true); 

     // execute 
     list.add(new Object()); 
    } 

    @Test 
    public void testC() { 

     // setup 
     ArrayList<Object> list = mock(ObjectArrayList.class); 
     when(list.add(any())).thenThrow(new AssertionError("can't get rid of me!")); 
     Mockito.reset(list); 
     when(list.add(any())).thenReturn(true); 

     // execute 
     list.add(new Object()); 
    } 

    /** 
    * Exists to work around the fact that mocking an ArrayList<Object> 
    * requires a cast, which causes "unchecked" warnings, that can only be suppressed... 
    */ 
    class ObjectArrayList extends ArrayList<Object> { 

    } 
} 

TestB विफल रहता है:

वास्तव में इस सवाल का जवाब करने के लिए।TestC दिखाता है कि नकली को रीसेट करने के लिए reset विधि का उपयोग कैसे किया जा सकता है और thenThrow कमांड को हटा दें।

ध्यान दें कि रीसेट हमेशा मेरे कुछ और जटिल उदाहरणों में काम नहीं करता है। मुझे संदेह है कि ऐसा हो सकता है क्योंकि वे Mockito.mock के बजाय PowerMockito.mock का उपयोग कर रहे हैं?