2010-06-21 16 views
11

मैं नियंत्रक की Index कार्रवाई का परीक्षण करने का प्रयास कर रहा हूं। कार्रवाई का उपयोग किसी डोमेन Customer ऑब्जेक्ट को मानचित्र मॉडल TestCustomerForm पर मैप करने के लिए करती है। हालांकि यह काम करता है मैं Index कार्रवाई से प्राप्त परिणामों का परीक्षण करने का सबसे अच्छा तरीका हूं।एक व्यूमोडेल को मैप करने के लिए ऑटोमैपर का उपयोग करने के बाद मुझे और किस प्रकार परीक्षण करना चाहिए?

नियंत्रक के सूचकांक कार्रवाई इस तरह दिखता है:

public ActionResult Index() 
{ 
    TestCustomerForm cust = Mapper.Map<Customer, 
     TestCustomerForm>(_repository.GetCustomerByLogin(CurrentUserLoginName)); 

    return View(cust); 
} 

और इसकी TestMethod इस तरह दिखता है:

[TestMethod] 
public void IndexShouldReturnCustomerWithMachines() 
{ 
    // arrange 
    var customer = SetupCustomerForRepository(); // gets a boiler plate customer 
    var testController = CreateTestController(); 

    // act 
    ViewResult result = testController.Index() as ViewResult; 

    // assert 
    Assert.AreEqual(customer.MachineList.Count(), 
     (result.ViewData.Model as TestCustomerForm).MachineList.Count()); 
} 

CreateTestController विधि मैं Rhino.Mocks का प्रयोग कर एक ग्राहक भंडार नकली और यह करने के लिए सेट अप करने के लिए ग्राहक को SetupCustomerForRepository से वापस करें। इस तरह से मुझे पता है कि भंडार इच्छित ग्राहक को वापस कर देगा जब Index कार्रवाई कॉल _repository.GetCustomerByLogin(CurrentUserLoginName) पर कॉल करेगी। इसलिए, मुझे लगता है कि IndexShouldReturnCustomerWithMachines को संतुष्ट करने के लिए एक समान गणना पर्याप्त है।

उन सभी ने कहा कि मैं इस बात से चिंतित हूं कि मुझे क्या परीक्षण करना चाहिए।

  1. result.ViewData.Model as TestCustomerForm डालने के लिए यह अजीब लगता है। क्या यह वास्तव में एक मुद्दा है? यह मुझे चिंतित करता है क्योंकि इस उदाहरण में मैं वास्तव में परीक्षण संचालित विकास नहीं कर रहा हूं और ऐसा लगता है कि मैं परीक्षण को पूरा करने के लिए एक विशेष कार्यान्वयन पर भरोसा कर रहा हूं।
  2. क्या सही मैपिंग सुनिश्चित करने के लिए और अधिक उचित परीक्षण हैं?
  3. क्या मुझे TestCustomerForm से प्रत्येक मैप की गई संपत्ति का परीक्षण करना चाहिए?
  4. क्या अधिक सामान्य नियंत्रक कार्रवाई परीक्षण हैं जो मुझे करना चाहिए?

    public interface IMapper<TSource, TDest> 
    { 
        TDest Map(TSource source); 
    } 
    
    public CustomerToTestCustomerFormMapper: IMapper<Customer, TestCustomerForm> 
    { 
        static CustomerToTestCustomerFormMapper() 
        { 
         // TODO: Configure the mapping rules here 
        } 
    
        public TestCustomerForm Map(Customer source) 
        { 
         return Mapper.Map<Customer, TestCustomerForm>(source); 
        } 
    } 
    

    इसके बाद आप नियंत्रक में इस पारित:

उत्तर

15

यह एक कारण है कि हम ऑटोमैपर को कस्टम एक्शन रिसेट या एक्शनफ़िल्टर में क्यों ले जाते हैं। किसी बिंदु पर, आप केवल यह जांचना चाहते हैं कि आपने Foo को FooDto में मैप किया है, लेकिन वास्तविक मैपिंग का जरूरी नहीं है। ऑटोमैपर को परत सीमाओं में ले जाकर (जैसे कि नियंत्रक के बीच में), आप केवल यह जांच सकते हैं कि आप ऑटोमैपर को क्या कह रहे हैं।

यह व्यूअरसेट का परीक्षण करने के समान है। आप एक नियंत्रक से परीक्षण नहीं करते हैं कि एक दृश्य प्रस्तुत किया गया था, बल्कि यह कि आपने एमवीसी को ऐसे और इस तरह के दृश्य प्रस्तुत करने के लिए कहा था।हमारी कार्रवाई परिणाम हो जाता है:

public class AutoMapViewResult : ActionResult 
{ 
    public Type SourceType { get; private set; } 
    public Type DestinationType { get; private set; } 
    public ViewResult View { get; private set; } 

    public AutoMapViewResult(Type sourceType, Type destinationType, ViewResult view) 
    { 
     SourceType = sourceType; 
     DestinationType = destinationType; 
     View = view; 
    } 

    public override void ExecuteResult(ControllerContext context) 
    { 
     var model = Mapper.Map(View.ViewData.Model, SourceType, DestinationType); 

     View.ViewData.Model = model; 

     View.ExecuteResult(context); 
    } 
} 
एक आधार नियंत्रक वर्ग पर एक सहायक विधि के साथ

:

protected AutoMapViewResult AutoMapView<TDestination>(ViewResult viewResult) 
{ 
    return new AutoMapViewResult(viewResult.ViewData.Model.GetType(), typeof(TDestination), viewResult); 
} 

कौन सा तो नियंत्रक बनाता है अब केवल क्या बजाय वास्तविक मानचित्रण प्रदर्शन करने से/मैप करने के लिए, निर्दिष्ट :

public ActionResult Index(int minSessions = 0) 
{ 
    var list = from conf in _repository.Query() 
       where conf.SessionCount >= minSessions 
       select conf; 

    return AutoMapView<EventListModel[]>(View(list)); 
} 

इस बिंदु पर, मैं केवल, परीक्षण "यकीन है कि आप इस गंतव्य FooDto प्रकार को यह फू वस्तु मानचित्रण कर रहे हैं", वास्तव में mappi प्रदर्शन करने की जरूरत के बिना की जरूरत है एनजी।

संपादित करें:

यहाँ एक परीक्षण टुकड़ा का एक उदाहरण है:

var actionResult = controller.Index(); 

actionResult.ShouldBeInstanceOf<AutoMapViewResult>(); 

var autoMapViewResult = (AutoMapViewResult) actionResult; 

autoMapViewResult.DestinationType.ShouldEqual(typeof(EventListModel[])); 
autoMapViewResult.View.ViewData.Model.ShouldEqual(queryResult); 
autoMapViewResult.View.ViewName.ShouldEqual(string.Empty); 
+0

ग्रेट उत्तर जो बहुत समझ में आता है। वंशावली के लिए क्या आप अपना टेस्ट स्टेटमेंट जोड़ना चाहते हैं? – ahsteele

+1

यह नई वेबएपी के साथ कैसे काम करेगा, जहां मेरी गेट विधि एक आईनेमेरेबल लौट रही है और कोई कार्रवाई परिणाम नहीं है? – shashi

+0

@ सैसीबॉय मैं वेब एपीआई के साथ एक पृथक सेवा परत का उपयोग करता हूं, जहां आप स्वयं का एक समान अमूर्त बना सकते हैं। –

2

मैं शायद AutoMapper के बीच युग्मन और एक अमूर्त शुरू करने से नियंत्रक अलग हैं

public HomeController: Controller 
{ 
    private readonly IMapper<Customer, TestCustomerForm> _customerMapper; 
    public HomeController(IMapper<Customer, TestCustomerForm> customerMapper) 
    { 
     _customerMapper = customerMapper; 
    } 

    public ActionResult Index() 
    { 
     TestCustomerForm cust = _customerMapper.Map(
      _repository.GetCustomerByLogin(CurrentUserLoginName) 
     ); 
     return View(cust); 
    } 
} 

और अपने इकाई परीक्षण में आप इस मैपर को रोकने के लिए अपने पसंदीदा मॉकिंग फ्रेमवर्क का उपयोग करेंगे।

+0

इन परीक्षणों मूल्य के कम अंत में कर रहे हैं। यदि आप ऑटोमैपर का मज़ाक उड़ाते हैं तो आप वास्तव में क्या परीक्षण कर रहे हैं, उस मानचित्र को कॉल किया जाता है? कोई फ्लो लॉजिक इत्यादि नहीं है .. यह सिर्फ उच्च परीक्षण कवरेज प्राप्त करने देता है। जब आपके नियंत्रक उस पतले होते हैं (जटिलता बाइंडर्स, फ़िल्टर, एक्शन इनवॉकर्स इत्यादि में स्थानांतरित होती है ..) तो बस "यूनिट" परीक्षण न करें (लौ की प्रतीक्षा करें) –

+0

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

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

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