2010-11-23 11 views
7

मैं इस स्थिर सहायक समारोह है:मैं VisualTreeHelper का उपयोग करने वाली किसी चीज़ का परीक्षण कैसे कर सकता हूं?

public static DependencyObject GetParentObject(DependencyObject child) 
    { 
     if (child == null) return null; 
     ContentElement contentElement = child as ContentElement; 

     if (contentElement != null) 
     { 
      var parent = ContentOperations.GetParent(contentElement); 
      if (parent != null) return parent; 

      var fce = contentElement as FrameworkContentElement; 
      return fce != null ? fce.Parent : null; 
     } 

     //if it's not a ContentElement, rely on VisualTreeHelper 
     return VisualTreeHelper.GetParent(child); 
    } 

यह एक वास्तविक आवेदन में काम करता है, लेकिन मैं इसके लिए कुछ इकाई परीक्षण लिखने की कोशिश कर रहा हूँ।

[Test] 
    public void GetParentObject_returns_immediate_parent() 
    { 
     var contentControl = new ContentControl(); 
     var textBox = new TextBox(); 

     contentControl.BeginInit(); 
     contentControl.Content = textBox; 
     contentControl.EndInit(); 

     var result = UIHelper.GetParentObject(textBox); 
     Assert.AreSame(contentControl, result); 
    } 

दुर्भाग्य से यह विफल रहता है क्योंकि VisualTreeHelper अशक्त लौटने: यहाँ मेरा पहला प्रयास है। मैं एक दृश्य पेड़ का नकल कैसे कर सकता हूं जो काम करेगा?

उत्तर

2

यही कारण है कि सांख्यिकी समस्याग्रस्त हैं।

आप एक इंटरफेस के पीछे कार्यक्षमता को सार कर सकते हैं और एक स्थिर कार्यान्वयन बना सकते हैं जो स्थैतिक विधि का उपयोग करता है। फिर आप निर्भरता इंजेक्शन का उपयोग कर सकते हैं, जो इस इकाई परीक्षण को छोटा बनाता है - iisualTreeHelper पर निर्भरता का नकल करें या अपने स्वयं के स्टब कार्यान्वयन को रोल करें जिसे आप असाइन किए गए किसी भी मान को वापस करने के लिए कॉन्फ़िगर कर सकते हैं।

public class Foo 
{ 
    static IVisualTreeHelper visualTreeHelper; 

    static Foo() 
    { 
     Foo.visualTreeHelper = new FrameworkVisualTreeHelper(); 
    } 

    public Foo(IVisualTreeHelper visualTreeHelper) 
    { 
     Foo.visualTreeHelper = visualTreeHelper; 
    } 

    public static DependencyObject GetParentObject(DependencyObject child) 
    { 
     if (child == null) return null; 
     ContentElement contentElement = child as ContentElement; 

     if (contentElement != null) 
     { 
      var parent = ContentOperations.GetParent(contentElement); 
      if (parent != null) return parent; 

      var fce = contentElement as FrameworkContentElement; 
      return fce != null ? fce.Parent : null; 
     } 

     //if it's not a ContentElement, rely on the IVisualTreeHelper 
     return visualTreeHelper.GetParent(child); 
    } 
} 

public interface IVisualTreeHelper 
{ 
    DependencyObject GetParent(DependencyObject reference); 
} 

public class FrameworkVisualTreeHelper : IVisualTreeHelper 
{ 
    public DependencyObject GetParent(DependencyObject reference) 
    { 
     return VisualTreeHelper.GetParent(reference); 
    } 
} 

जाहिर है, आप अपने इंटरफेस और डिफ़ॉल्ट कार्यान्वयन के लिए अन्य VisualTreeHelper तरीकों को जोड़ने के लिए है, तो आप अन्य तरीकों कहीं और का उपयोग कर रहे पड़ सकता है।

यह अभी भी पूरी तरह से साफ नहीं है क्योंकि आप जिस यूनिट का परीक्षण कर रहे हैं वह स्वयं स्थिर है, और जब आप अपने UIHelper क्लास 'स्थिर तरीकों पर निर्भर किसी भी वर्ग का परीक्षण करने का प्रयास करते हैं तो आप एक ही समस्या में भागने जा रहे हैं ।

-1

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

2

इस उत्तर के आधार पर printing documents via Wpf-controls and convert to XPS पर मैं दृश्य वृक्ष बनाने के लिए निम्न विस्तार विधि के साथ आया था। यह एनयूएनआईटी के भीतर एसटीए-थ्रेड या कुछ भी के बिना अच्छी तरह से काम करता है।

/// <summary> 
/// Render a UIElement such that the visual tree is generated, 
/// without actually displaying the UIElement 
/// anywhere 
/// </summary> 
public static void CreateVisualTree(this UIElement element) 
{ 
    var fixedDoc = new FixedDocument(); 
    var pageContent = new PageContent(); 
    var fixedPage = new FixedPage(); 
    fixedPage.Children.Add(element); 
    pageContent.ToMaybeOf<IAddChild>().Do(c => c.AddChild(fixedPage)); 
    fixedDoc.Pages.Add(pageContent); 

    var f = new XpsSerializerFactory(); 
    var w = f.CreateSerializerWriter(new MemoryStream()); 
    w.Write(fixedDoc); 
} 

कृपया ध्यान दें कि

  • अन्य जवाब रीच-dll कि एपीआई मैं देख रहा हूँ की तरह नहीं दिखता के API का उपयोग करता। मुझे लगता है वहाँ .NET Framework संस्करण 3.5 और 4.0
  • ToMaybeOf सामान मूल रूप से pageContentIAddChild रूप में मानते हैं और उस इंटरफ़ेस
  • पर एक क्रिया करने का मतलब के बीच मतभेद हैं कि इस होगा के प्रकार विंडो एक तत्व के साथ नहीं काम चूंकि तत्व को अनिवार्य रूप से एक बच्चे के रूप में एक दृश्य के रूप में जोड़ा जाता है और विंडो इस बारे में कड़वाहट से शिकायत करेगी।
+0

मैं 'pageContent' को' IAddChild' डाली और ऑपरेशन सीधे प्रदर्शन किया, बल्कि 'ToMaybeOf' और' Do' पर भरोसा करने की बजाय: '((IAddChild) pageContent) .AddChild (fixedPage);' –

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

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