2012-05-23 4 views
18

मैं यह जानना चाहता हूं कि मैं एक विधि का नकल कैसे कर सकता हूं जो दूसरी बार इसे अलग-अलग मूल्य देता है पहर। उदाहरण के लिए, इस तरह कुछ:राइनोमोक्स - एक विधि का मजाक कर रहा है जिसका रिटर्न वैल्यू बदलता है (यहां तक ​​कि जब एक ही पैरामीटर पारित किया जाता है) एकाधिक कॉल

public interface IApplicationLifetime 
{ 
    int SecondsSinceStarted {get;} 
} 

[Test] 
public void Expected_mock_behaviour() 
{ 
    IApplicationLifetime mock = MockRepository.GenerateMock<IApplicationLifetime>(); 

    mock.Expect(m=>m.SecondsSinceStarted).Return(1).Repeat.Once(); 
    mock.Expect(m=>m.SecondsSinceStarted).Return(2).Repeat.Once(); 

    Assert.AreEqual(1, mock.SecondsSinceStarted); 
    Assert.AreEqual(2, mock.SecondsSinceStarted); 
} 

क्या ऐसा कुछ भी है जो इसे संभव बनाता है? गेटटर के लिए उप-लागू करने के अलावा जो राज्य मशीन लागू करता है?

चीयर्स दोस्तों,

एलेक्स

+0

आदेशित और अनियंत्रित मोजे पर नज़र डालें: http://ayende.com/wiki/Rhino%20Mocks%20Ordered%20and%20Unordered.ashx – Maciej

+2

आपके द्वारा प्रदान किए गए कोड के साथ क्या गलत है? 'दोहराना। एक बार() ' –

+0

@lazyberezovsky काम करना चाहिए m.SecondsSinceStarted 2 के लिए पहली कॉल, – AlexC

उत्तर

28

आप .WhenCalled विधि के साथ वापसी मूल्यों को रोक सकता।

int invocationsCounter = 1; 
const int IgnoredReturnValue = 10; 
mock.Expect(m => m.SecondsSinceLifetime) 
    .WhenCalled(mi => mi.ReturnValue = invocationsCounter++) 
    .Return(IgnoredReturnValue); 

Assert.That(mock.SecondsSinceLifetime, Is.EqualTo(1)); 
Assert.That(mock.SecondsSinceLifetime, Is.EqualTo(2)); 

संपादित करें:: ध्यान रखें कि आपको .Return विधि के माध्यम से मूल्य प्रदान करने की आवश्यकता है, तथापि राइनो बस इसे अगर ReturnValue विधि मंगलाचरण से बदल दिया जाता है पर ध्यान नहीं देगा

थोड़ा अधिक के आसपास खुदाई, ऐसा लगता है कि .Repeat.Once() वास्तव में इस मामले में काम करता है और एक ही परिणाम प्राप्त करने के लिए इस्तेमाल किया जा सकता:

mock.Expect(m => m.SecondsSinceStarted).Return(1).Repeat.Once(); 
mock.Expect(m => m.SecondsSinceStarted).Return(2).Repeat.Once(); 
mock.Expect(m => m.SecondsSinceStarted).Return(3).Repeat.Once(); 

लगातार कॉल पर 1, 2, 3 लौटाएगा।

+0

जैसा कि मैं समझता हूं, अनुक्रमिक संख्याओं के अलावा किसी अन्य चीज़ के लिए उसे सरणी बनाना चाहिए और सूचकांक द्वारा मूल्यों को वापस करना चाहिए? –

+0

मैं मानता हूं कि यह विधि काम करती है, लेकिन यह अनिवार्य रूप से एक राज्य मशीन को लागू करने जैसा ही है, जिसका मैंने उल्लेख किया है कि मैं बचने की कोशिश कर रहा हूं (यानी।अगर मैं दूसरी कॉल पर 11 लौटना चाहता था, तो मुझे कुछ करना होगा जैसे "अगर (invocationsCounter == 1) 1 लौटाएं; अन्यथा अगर (invocationsCounter == 2) 11 लौटाएं;" जो एक राज्य मशीन की तरह दिखता है। – AlexC

+0

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

0

क्या समय विधि निर्धारित करने में निर्धारित कारक है? यदि ऐसा है, तो मैं समय बीतने का प्रयास करने की कोशिश करूंगा ताकि आपके परीक्षण में इसका प्रत्यक्ष नियंत्रण हो।

GetElapsedTime() नामक एक सदस्य के साथ ITimeProvider नामक इंटरफ़ेस की तरह कुछ और फिर अपने पूरे एप्लिकेशन में उपयोग करने के लिए एक डिफ़ॉल्ट कार्यान्वयन बनाएं।

फिर जब आप परीक्षण कर रहे हों, तो एक मजाकिया ITimeProvider में पास करें ताकि आप अपने आवेदन द्वारा समय बीतने के लिए क्या समझते हैं उसे नियंत्रित कर सकें।

+0

असल में, समय की बात पूरी तरह से वर्णन किए बिना एक आसान उदाहरण था कि मैं परीक्षण करने की कोशिश कर रहा हूं। फिर भी, अगर मैं एक ITimeProvider का नकल करना चाहता था, जिसमें GetElapsedTime() विधि थी, तो समस्या तब भी मौजूद होगी जब मैं एक यूनिट टेस्ट लिखना चाहता था जिसे GetElapsedTime() को दो बार कहा जाता था, और मेरी नकली ITimeProvider को एक अलग वापस करना चाहता था प्रत्येक कॉल के लिए समय। – AlexC

+0

क्या आपके पास ITimeProvider संपत्ति निर्भरता हो सकता है? इस प्रकार प्रत्येक कॉल से पहले नए मोक्स इंजेक्ट करने में सक्षम होना? इसके बावजूद, यदि आपका समय आप से निपट नहीं रहा है, तो मेरा जवाब संभवतः बेकार है ... – theMothaShip

+0

मेरा प्रश्न इस बारे में अधिक था कि राइनोमोक्स जेनरेट किए गए मैक्स/स्टब्स के साथ इस प्रकार की बातचीत का समर्थन करता है, और इस बारे में कम कि मैं इसके आसपास कैसे काम कर सकता हूं, इसे समर्थित नहीं किया जाना चाहिए। हालांकि धन्यवाद। – AlexC

5

सीधे शब्दों में

mock.Expect(m=>m.SecondsSinceStarted).Return(1).Repeat.Once(); 
mock.Expect(m=>m.SecondsSinceStarted).Return(2).Repeat.Once(); 

इस का उपयोग दूसरी कॉल के दौरान पहली कॉल के दौरान 1, और 2 वापस आ जाएगी। कम से कम RhinoMocks 3.6.0.0

+0

यह निश्चित रूप से जब मैं – AlexC

+0

से ऊपर परीक्षण चलाता हूं, तो यह निश्चित रूप से संघर्ष करता है जैसा कि स्वीकृत उत्तर में बताया गया है, यह सही है, मेरा परीक्षण केवल असफल रहा क्योंकि मैं अनजाने में कुछ कदम उठा रहा था और मूल्यांकन कर रहा था। Upvoted। – AlexC

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