अगली बार जब यह कहा जाता है तो कुछ अलग करने के लिए मॉकिटो मॉक ऑब्जेक्ट को कैसे बताया जाए?


202

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

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.

    }

}

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

जवाबों:


43

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

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


438

तुम भी लगातार कॉल (2.8.9 एपीआई में # 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
    }
}

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

10
@JustinMuller - यह एक अलग जवाब के लायक है, मुझे लगता है (टिप्पणी के विपरीत)
ब्रायन एग्न्यू

16
इस मामले में यह जवाब सही नहीं है। यदि आप 0 और 1 को वापस करने के लिए इस विधि को रोकते हैं, तो आप तब तक ठीक रहेंगे जब तक आप दौड़ते हैं test1और फिर test2। लेकिन यह हो सकता है कि आपका निरंतर एकीकरण वातावरण परीक्षण को अन्य क्रम में चलाएगा। या यह हो सकता है कि आप पहले test2भाग के बिना खुद को चलाना चाहें test1, जिस स्थिति में यह विफल हो जाएगा। यूनिट परीक्षणों को हमेशा एक दूसरे से स्वतंत्र होना चाहिए ; और व्यक्तिगत परीक्षणों, या परीक्षणों के किसी विशेष आदेश पर निर्भरता के बीच कभी भी निर्भरता नहीं होनी चाहिए । जबकि thenReturnबयानों का सिलसिला ...
दाऊद इब्न करीम

4
... इसके उपयोग हैं, जैसा कि एकल के लिए varargs का उपयोग करता है thenReturn, यह इस विशेष मामले में एक सही समाधान नहीं है। मुझे ऐसा प्रतीत होता है कि यहाँ उत्थानकर्ताओं की भीड़ सबसे अधिक संभावना को समझने में विफल रही है।
दाऊद इब्न करीम

2
JUnit ही बिना परीक्षण ताकि यह सुनिश्चित नहीं करता है@FixMethodOrder
रोजर

29

उन सभी के लिए जो कुछ वापस करने के लिए खोज करते हैं और फिर एक और कॉल थ्रो अपवाद के लिए:

    when(mockFoo.someMethod())
            .thenReturn(obj1)
            .thenReturn(obj2)
            .thenThrow(new RuntimeException("Fail"));

या

    when(mockFoo.someMethod())
            .thenReturn(obj1, obj2)
            .thenThrow(new RuntimeException("Fail"));


14

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

आपको विभिन्न कॉल पर अलग-अलग ऑब्जेक्ट वापस करने की आवश्यकता है:

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

क्लासिक मोक्स के लिए:

when(this.mockFoo.someMethod()).thenReturn(obj1, obj2);

या एक अपवाद के साथ फेंका जा रहा है:

when(mockFoo.someMethod())
        .thenReturn(obj1)
        .thenThrow(new IllegalArgumentException())
        .thenReturn(obj2, obj3);
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.