2010-01-28 17 views
6

मैं निम्नलिखित और संक्षिप्त बनाने के तरीकों की तलाश में हूं।राइनो मोक्स के साथ ड्रवाई प्राप्त करना

public class MyTests 
{ 
    IPresenter presenter; 

    [SetUp] 
    public void SetUp() 
    { 
     presenter = MockRepository.GenerateStub<IPresenter>(); 
    } 

    ... 
} 

विशेष रूप से जब नकली बनाने प्रकार फिर से निर्दिष्ट करने बेमानी लगता है। उदाहरण के लिए मैं इसे इस तरह से लिख सकते हैं और प्रतिबिंब का उपयोग प्रकार प्राप्त करने के लिए और स्वचालित रूप से ठूंठ बनाएँ:

public class MyTests 
{ 
    IPresenter presenter; 

    [SetUp] 
    public void SetUp() 
    { 
     Stub(x => x.presenter); 
    } 

    void Stub(Expression<Func<MyTests, object>> expression) 
    { 
     ... 
    } 
} 

यह काम करेगा लेकिन संकलक अब पता लगा सकते हैं कि प्रस्तोता सौंपा और चेतावनी जारी करने के लिए शुरू होता है है। यह ReSharper भी बहुत दुखी करता है।

क्या कोई बेहतर दृष्टिकोण सुझा सकता है?

उत्तर

5

यह विवादास्पद हो सकता है, लेकिन मैं यूनिट परीक्षणों में डीआरवाई-नेस * की बजाय पठनीयता का पक्ष लेता हूं।

दूसरे शब्दों में, सेट अप विधियां मेरे यूनिट परीक्षणों में मौजूद नहीं हैं। वे केवल एकीकरण परीक्षण के लिए उपयोग किया जाता है। मेरा मानना ​​है कि XUnit.NET भी इस रुख को लेता है।

तो अपने प्रश्न का उत्तर देने के लिए, मैं वास्तव में आपके प्रत्येक परीक्षण में नकली प्रस्तुतियों को स्थापित करने की चिंता नहीं करता जिसके लिए एक की आवश्यकता होती है। कुछ परीक्षणों को नकली प्रस्तुति की आवश्यकता नहीं हो सकती है, इसलिए परीक्षण चलाने से पहले एक सेट अप करना जरूरी नहीं है।

** स्वाभाविक रूप से, मेरी इकाई परीक्षण अवधि दस लाइन औसत कहती है, यदि यह बढ़ जाती है या परीक्षण स्थापित करने का दायरा (एएए - व्यवस्था, अधिनियम सम्मिलन के बाद) बड़ा होता है, तो तभी मैं डुप्लिकेशंस को हटा दूंगा और सहायक बनाउंगा तरीकों। इस बिंदु को साफ़ करने के लिए, क्लीनर परीक्षणों के लिए, आप एक बेस टेस्ट क्लास बना सकते हैं जिसमें सहायक विधियां और अन्य सेट अप कोड शामिल हैं। *

+1

मैं ज्यादातर इस (इसलिए +1) से सहमत हूं, लेकिन यह भी सुझाव देना चाहूंगा कि आप मोक्स के साथ परीक्षणों के लिए एक आंतरिक कक्षा बना सकते हैं यदि आप उनका उपयोग करके बहुत सारे परीक्षण मामले में जा रहे हैं। – jonnii

+0

@ जॉनी - आपने मुझे मेरे संपादन में हराया। लेकिन मैं सहमत हूं। – Finglas

+0

@ फ़िंगलास यह अनुबंध का एक चक्र है। आइए पीठ पर एक-दूसरे को पॅट करें;) – jonnii

3

हां, [Setup] और सदस्य चर का उपयोग न करें, इसके बजाय सृजन विधियों के साथ Fixture Objects लिखें।

स्थिरता ऑब्जेक्ट केवल उचित नकली और स्थिरता के अन्य हिस्सों को पकड़ लेगा।

मैं व्यक्तिगत रूप से AutoFixture as a Fixture Object का उपयोग, और यह बूट करने के लिए एक ऑटो मजाक कंटेनर के रूप में स्थापित है, तो मैं किसी भी नकली कोड लिखने के लिए जब तक कि मैं स्पष्ट रूप से कुछ व्यवहार परिभाषित करने की जरूरत नहीं है।

यहाँ हाल ही में एक नमूना इकाई परीक्षण है:

[TestMethod] 
public void DeleteProductWillDeleteProductFromRepository() 
{ 
    // Fixture setup 
    var fixture = new ServiceFixture(); 
    var id = fixture.CreateAnonymous<int>(); 
    var repMock = fixture.FreezeMoq<ProductRepository>(); 

    var sut = fixture.CreateAnonymous<ProductManagementService>(); 
    // Exercise system 
    sut.DeleteProduct(id); 
    // Verify outcome 
    repMock.Verify(r => r.DeleteProduct(id)); 
    // Teardown 
} 

इस मामले में, repMock Moq द्वारा बनाई गई है, लेकिन मैं बजाय राइनो Mocks उपयोग करने के लिए इसे सेट अप किया जा सकता था।

+1

, XUnit FTW! – mxmissile

+0

आप प्रत्येक विधि में अतिरिक्त सेट अप के लिए एक सदस्य चर + प्रारंभकर्ता का व्यापार कर रहे हैं जो कुछ परीक्षणों के साथ जुड़ने जा रहा है। ऑटो मॉकिंग कुछ ऐसा है जो मुझे देखना चाहिए, धन्यवाद। –

0

यह सी # के साथ एक सामान्य दर्द है, जिससे यह इस प्रकार का अनुमान नहीं लगाता है विधि परिणाम (जावा के विपरीत), और यह कई स्थितियों में दर्दनाक है (बस एक और उदाहरण देने के लिए, जहां आप एक deserialising विधि को लागू करना चाहते हैं)। व्यक्तिगत रूप से मुझे var कीवर्ड का उपयोग करना पसंद नहीं है, क्योंकि मैं देखना चाहता हूं कि मेरी ऑब्जेक्ट्स का प्रकार क्या है, मैं टेम्पलेट में टाइप नाम को छोड़ना पसंद करूंगा।

वैसे भी, यदि मेरे परीक्षण अच्छे और छोटे हैं, तो मैं प्रत्येक टेस्ट केस के अंदर सभी मोजे शुरू करना चाहता हूं। इस तरह आप अन्य परीक्षणों से अलगाव में प्रत्येक परीक्षण को देख सकते हैं और तुरंत देख सकते हैं कि वहां क्या हो रहा है। अगर वे लंबे समय तक चले जाते हैं, हालांकि मैं आपके प्रश्न की शुरुआत में चिपकने वाले गंदे तरीके का उपयोग करता हूं।

1

माइकल फेदरस पर इस पर एक उत्कृष्ट दृश्य है (उसकी प्रस्तुति http://www.ndc2010.no/index.aspx?id=361621 देखें)।बिल्डर्स बनाएं और सभी प्रकार की सेटअप सामग्री के बजाय परीक्षणों में इसका उपयोग करें।

तरह:

//The Class to Test 
    public class ObjectY 
    { 
     public string DoThis(IObjectX objectX) 
     { 
      return objectX.id + objectX.name; 
     } 
    } 


    [Test] 
    //The test 
    public void CreaeteTestData() 
    { 
     //Almost prosa style creation of test data 
     var testData = new ObjectXBuilder().WithId(123).WithName("ABC").Build(); 

     Assert.That(new ObjectY().DoThis(testData), Is.EqualTo("123ABC")); 

    } 


    //The Builder class - Provides easy creation testdata. 
    internal class ObjectXBuilder 
    { 
     private MockRepository _mockRepository; 
     private IObjectX _objectX; 

     public ObjectXBuilder() 
     { 
      _mockRepository = new MockRepository(); 
      _objectX = _mockRepository.Stub<IObjectX>(); 
     } 

     public ObjectXBuilder WithName(string name) 
     { 
      _objectX.name = name; 
      return this; 
     } 

     public ObjectXBuilder WithId(long id) 
     { 
      _objectX.id = id; 
      return this; 
     } 

     public IObjectX Build() 
     { 
      _mockRepository.ReplayAll(); 
      return _objectX; 
     } 

    } 
के साथ कोई [सेटअप] या [कटाव]