2010-11-18 5 views
132

तो, मैं वर्ग स्तर पर एक स्थिर चर के रूप में एक नकली वस्तु बना रहा हूं ... एक परीक्षण में, मुझे एक निश्चित मूल्य वापस करने के लिए Foo.someMethod() चाहिए, जबकि एक और परीक्षण में, मैं इसे एक अलग मूल्य वापस करना चाहता हूं । मेरी समस्या यह है कि ऐसा लगता है कि इसे ठीक से काम करने के लिए मुझे मोज़े का पुनर्निर्माण करने की आवश्यकता है। मैं mocks के पुनर्निर्माण से बचना चाहता हूं, और केवल प्रत्येक परीक्षण में एक ही वस्तु का उपयोग करें।अगली बार इसे कॉल करने के लिए कुछ अलग करने के लिए एक मॉकिटो मॉक ऑब्जेक्ट को कैसे बताना है?

class TestClass { 

    private static Foo mockFoo; 

    @BeforeClass 
    public static void setUp() { 
     mockFoo = mock(Foo.class); 
    } 

    @Test 
    public void test1() { 
     when(mockFoo.someMethod()).thenReturn(0); 

     TestObject testObj = new TestObject(mockFoo); 

     testObj.bar(); // calls mockFoo.someMethod(), receiving 0 as the value 

    } 

    @Test 
    public void test2() { 
     when(mockFoo.someMethod()).thenReturn(1); 

     TestObject testObj = new TestObject(mockFoo); 

     testObj.bar(); // calls mockFoo.someMethod(), STILL receiving 0 as the value, instead of expected 1. 

    } 

} 

दूसरे टेस्ट में, मैं अभी भी मूल्य जब testObj.bar() कहा जाता है के रूप में 0 प्राप्त कर रहा हूँ ... इस को हल करने का सबसे अच्छा तरीका क्या है? ध्यान दें कि मुझे पता है कि मैं प्रत्येक परीक्षण में Foo के एक अलग मॉक का उपयोग कर सकता हूं, हालांकि, मुझे mockFoo से कई अनुरोधों को चेन करना होगा, जिसका अर्थ है कि मुझे प्रत्येक परीक्षण में चेनिंग करना होगा।

उत्तर

36

सबसे पहले नकली स्थिर नहीं बनाते हैं। इसे एक निजी क्षेत्र बनाओ। बस अपनी सेटअप क्लास को @Before@BeforeClass में डालें। यह एक गुच्छा चलाया जा सकता है, लेकिन यह सस्ता है।

दूसरा, जिस तरह से आपके पास अभी यह है, परीक्षण के आधार पर कुछ अलग करने के लिए नकली पाने का सही तरीका है।

341

आप Stub Consecutive Calls (2.8.9 2.i में # 10) भी कर सकते हैं। इस मामले में, आप एकाधिक का उपयोग करेंगे, फिर कॉल या एक फिर रीटर्न एकाधिक पैरामीटर (varargs) के साथ कॉल करें।

import static org.junit.Assert.assertEquals; 
import static org.mockito.Mockito.mock; 
import static org.mockito.Mockito.when; 

import org.junit.Before; 
import org.junit.Test; 

public class TestClass { 

    private Foo mockFoo; 

    @Before 
    public void setup() { 
     setupFoo(); 
    } 

    @Test 
    public void testFoo() { 
     TestObject testObj = new TestObject(mockFoo); 

     assertEquals(0, testObj.bar()); 
     assertEquals(1, testObj.bar()); 
     assertEquals(-1, testObj.bar()); 
     assertEquals(-1, testObj.bar()); 
    } 

    private void setupFoo() { 
     mockFoo = mock(Foo.class); 

     when(mockFoo.someMethod()) 
      .thenReturn(0) 
      .thenReturn(1) 
      .thenReturn(-1); //any subsequent call will return -1 

     // Or a bit shorter with varargs: 
     when(mockFoo.someMethod()) 
      .thenReturn(0, 1, -1); //any subsequent call will return -1 
    } 
} 
+6

नाइस:

क्या आप भिन्न कॉल पर विभिन्न वस्तु वापस जाने के लिए की जरूरत है । उसे नहीं पता था। – OliverS

+1

यह मेरा सवाल हल हो गया, धन्यवाद टोनी! – seanhodges

+140

मुझे लगता है कि आप इस तथ्य का भी लाभ उठा सकते हैं कि .thenReturn() varargs लेता है, इसलिए कोड को छोटा किया जा सकता है: जब (mockFoo.someMethod())। फिर वापसी (0, 1, -1); –

0

जब() विधि के बजाय) जासूस() और doReturn (का उपयोग कर किसी को भी के लिए:

doReturn(obj1).doReturn(obj2).when(this.client).someMethod();