2012-11-20 22 views
9

मैं मॉकिटो के साथ एक ऑब्जेक्ट का मज़ाक उड़ा रहा हूं, इस ऑब्जेक्ट पर एक ही विधि को कई बार कहा जाता है और मैं हर बार एक ही मूल्य वापस करना चाहता हूं।मॉकिटो: एक ही विधि के लिए एकाधिक कॉल

LogEntry entry = null; // this is a field 
// This method is called once only. 
when(mockLogger.createNewLogEntry()).thenAnswer(new Answer<LogEntry>() { 
    @Override 
    public LogEntry answer(InvocationOnMock invocationOnMock) throws Throwable { 
    entry = new LogEntry(); 
    return entry; 
    } 
}); 
// This method can be called multiple times, 
// If called after createNewLogEntry() - should return initialized entry. 
// If called before createNewLogEntry() - should return null. 
when(mockLogger.getLogEntry()).thenAnswer(new Answer<LogEntry>() { 
    @Override 
    public LogEntry answer(InvocationOnMock invocationOnMock) throws Throwable { 
    return entry; 
    } 
}); 

समस्या है, ऐसा लगता है कि मेरी getLogEntry विधि केवल एक बार कहा जाता है:
यह है कि मैं क्या है। बाद के सभी आमंत्रणों के लिए, null इसके बदले वापस कर दिया गया है और मुझे परीक्षण में एनपीई मिलते हैं।
मैं सभी कॉल के लिए स्टब किए गए संस्करण का उपयोग करने के लिए मॉकिटो कैसे कह सकता हूं?

============================================== ===================
भविष्य की पीढ़ियों के

के लिए पोस्ट मार्टम मैं था कुछ अतिरिक्त जांच और हमेशा की तरह यह नहीं पुस्तकालय की गलती, यह मेरी गलती है । createNewLogEntry() पर कॉल करने से पहले मेरे कोड में getLogEntry() नामक विधियों में से एक। एनपीई बिल्कुल वैध था, परीक्षण वास्तव में मेरे कोड में एक बग मिला, मुझे मॉकिटो में बग नहीं मिला।

+0

सुंदर रहस्यमय। यह आम तौर पर काम करना चाहिए। मुझे लगता है कि मैं वहां कुछ प्रश्न फेंक दूंगा: 1) क्या आप निश्चित हैं कि यह प्रविष्टि है जो शून्य है और किसी भी तरह से mockLogger को कहीं भी शून्य पर रीसेट नहीं किया जा रहा है? 2) क्या यह संभव है कि मॉक लॉगर को मॉक किए गए तरीकों के बिना पुनर्निर्मित किया जा रहा है? उपर्युक्त कोड को उन तरीकों से फ्रेम करने में मददगार हो सकता है जो इसे परिभाषित करते हैं (एक टेस्ट विधि बनाम सेटअप)। अंत में, आप वास्तव में निष्पादित किए जा रहे कार्यों के बारे में सुनिश्चित करने के लिए, अपने उत्तर के इम्प्ले (या ब्रेकपॉइंट्स) में एक println आज़मा सकते हैं। –

+0

आपकी समस्या को पुन: उत्पन्न करने का प्रयास किया, एक समान दृष्टिकोण Mockito 1.9.5 ==> का उपयोग कर मेरे लिए काम करता है शायद आप मॉकिटो मेलिंग सूची के माध्यम से पूरे टेस्ट क्लास का कोड भेज सकते हैं? – s106mo

उत्तर

10

आपका स्टब काम करना चाहिए जैसा आप चाहते हैं। Mockito doc से:

एक बार टोंटदार, विधि हमेशा परवाह किए बिना यह कितनी बार कहा जाता है की टोंटदार मान प्रदान करेंगे।

+0

मैंने सवाल को सही किया, मैं वास्तव में तब Answers() का उपयोग कर रहा हूँ। –

1

क्या मुझे कुछ याद आ रहा है, या निम्नलिखित पर्याप्त होगा?

LogEntry entry = null; // this is a field 
when(mockLogger.createNewLogEntry()).thenAnswer(new Answer<LogEntry>() { 
    @Override 
    public LogEntry answer(InvocationOnMock invocationOnMock) throws Throwable { 
    if (entry == null) { 
     entry = new LogEntry(); 
    } 
    return entry; 
    } 
}); 
when(mockLogger.getLogEntry()).thenAnswer(new Answer<LogEntry>() { 
    @Override 
    public LogEntry answer(InvocationOnMock invocationOnMock) throws Throwable { 
    return entry; 
    } 
}); 

केवल काम करता है, तो entry == null है।

+0

createNewLogEntry() केवल एक बार बुलाया जाता है। उसके बादLogEntry() को कई बार कहा जा सकता है, लेकिन ऐसा लगता है कि मॉक किए गए संस्करण को केवल एक बार बुलाया जाता है, उसके बाद डिफ़ॉल्ट मान शून्य वापस आ जाता है। –

+2

ऐसा लगता है कि कुछ अजीब चल रहा है। जब भी विधि लागू की जाती है तो मॉकिटो को जवाब देना चाहिए और जवाब देना चाहिए। क्या आप वाकई अपने कोड/टेस्ट में किसी जगह या नकली को रीसेट नहीं कर रहे हैं? –

+0

मैंने चेक किया, केवल एक ही स्थान जिसे मैंने प्रविष्टि = शून्य सेट किया है ऊपर दिखाए गए सेटअप() विधि में है। मैं परीक्षण में कहीं भी इसे रीसेट नहीं करता हूं। मैं कुछ और डिबगिंग करूँगा, लेकिन जहां तक ​​मैं कह सकता हूं, getLogEntry() के लिए उत्तर केवल एक बार कहा जाता है। मैं कल और जांच करूंगा। –

4

जब तक मैं अगर तुम तो क्यों नहीं सरल करते प्रत्येक विधि मंगलाचरण के लिए एक ही वस्तु वापस करना चाहते हैं, कुछ याद कर रहा हूँ:

final LogEntry entry = new LogEntry() 
when(mockLogger.createNewLogEntry()).thenReturn(entry); 
when(mockLogger.getLogEntry()).thenReturn(entry); 

... 

verify(mockLogger).createNewLogEntry(); 
verify(mockLogger, times(???)).getLogEntry(); 

Mockito हर मिलान कॉल के लिए समान मान प्रदान करेंगे।

+0

यदि createNewLogEntry() को पहले कहा जाता है, तो logEntry() को प्राप्त करने के बाद की सभी कॉल प्रारंभिक प्रविष्टि को वापस करनी चाहिए।यदि createNewLogEntry() को पहले नहीं कहा जाता है, तो logEntry() को प्राप्त करने के लिए बाद की सभी कॉल शून्य होनी चाहिए। आपने जो प्रस्ताव दिया है वह इस तरह से काम नहीं करेगा। –

+1

यदि संभव हो, तो क्या आप इसे दो अलग-अलग परीक्षण मामलों में विभाजित कर सकते हैं? एक जहां 'createNewLogEntry' को दूसरी कहा जाता है जब यह नहीं होता है? यह चीजों को सरल बना सकता है। – Jonathan

+1

मेरा मानना ​​है कि आपका मतलब है 'फिर वापसी', न कि 'फिर जवाब'। –

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