2010-02-19 8 views
7

मैं अभी भी सामान्य रूप से जुड़े व्यवहारों को झुका रहा हूं, और एक नुकसान के लिए एक इकाई परीक्षण लिखना है।यूनिट परीक्षण एक संलग्न व्यवहार wpf

मैंने सच्चा बारबर के सिंच फ्रेमवर्क से नीचे कुछ कोड चिपकाया जो संलग्न व्यवहार के माध्यम से एक विंडो को बंद करने की अनुमति देता है। क्या कोई मुझे इसके लिए एक उदाहरण इकाई परीक्षण दिखा सकता है?

धन्यवाद!
Berryl

#region Close 

    /// <summary>Dependency property which holds the ICommand for the Close event</summary> 
    public static readonly DependencyProperty CloseProperty = 
     DependencyProperty.RegisterAttached("Close", 
      typeof(ICommand), typeof(Lifetime), 
       new UIPropertyMetadata(null, OnCloseEventInfoChanged)); 

    /// <summary>Attached Property getter to retrieve the CloseProperty ICommand</summary> 
    public static ICommand GetClose(DependencyObject source) 
    { 
     return (ICommand)source.GetValue(CloseProperty); 
    } 

    /// <summary>Attached Property setter to change the CloseProperty ICommand</summary> 
    public static void SetClose(DependencyObject source, ICommand command) 
    { 
     source.SetValue(CloseProperty, command); 
    } 

    /// <summary>This is the property changed handler for the Close property.</summary> 
    private static void OnCloseEventInfoChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) 
    { 
     var win = sender as Window; 
     if (win == null) return; 

     win.Closing -= OnWindowClosing; 
     win.Closed -= OnWindowClosed; 

     if (e.NewValue == null) return; 

     win.Closing += OnWindowClosing; 
     win.Closed += OnWindowClosed; 
    } 

    /// <summary> 
    /// This method is invoked when the Window.Closing event is raised. 
    /// It checks with the ICommand.CanExecute handler 
    /// and cancels the event if the handler returns false. 
    /// </summary> 
    private static void OnWindowClosing(object sender, CancelEventArgs e) 
    { 
     var dpo = (DependencyObject)sender; 
     var ic = GetClose(dpo); 
     if (ic == null) return; 

     e.Cancel = !ic.CanExecute(GetCommandParameter(dpo)); 
    } 

    /// <summary> 
    /// This method is invoked when the Window.Closed event is raised. 
    /// It executes the ICommand.Execute handler. 
    /// </summary> 
    static void OnWindowClosed(object sender, EventArgs e) 
    { 
     var dpo = (DependencyObject)sender; 
     var ic = GetClose(dpo); 
     if (ic == null) return; 

     ic.Execute(GetCommandParameter(dpo)); 
    } 

    #endregion 

उत्तर

5

संभवत: आपको अपने ICommand में एक लैम्ब्डा का प्रयोग कर एक DelegateCommand या एक RelayCommand का उपयोग कर जाएगा। इन दोनों के कई कार्यान्वयन मौजूद हैं और सिंच के पास कुछ समान हो सकता है। (एक उदाहरण के रूप में, उत्पादन प्रयोग के लिए नहीं) सच में सरल संस्करण:

public class DelegateCommand : ICommand { 
    private Action _execute = null; 

    public void Execute(object parameter) { 
     _execute(); 
    } 

    public DelegateCommand(Action execute) { 
     _execute = execute; 
    } 

    #region stuff that doesn't affect functionality 
    public bool CanExecute(object parameter) { 
     return true; 
    } 
    public event EventHandler CanExecuteChanged { 
     add { } 
     remove { } 
    } 
    #endregion 
} 

फिर अपने परीक्षण शरीर कुछ इस तरह दिख सकता है:

bool wascalled = false; 

var execute = new DelegateCommand(
    () => { 
     wascalled = true; 
    }); 

var window = new Window(); 
SomeClass.SetClose(window, execute); 

// does the window need to be shown for Close() to work? Nope. 

window.Close(); 

AssertIsTrue(wascalled); 

यह एक अति सरल उदाहरण है। निश्चित रूप से ऐसे अन्य परीक्षण हैं जिन्हें आप करना चाहते हैं, इस मामले में आपको DelegateCommand का पूर्ण कार्यान्वयन बनाना या ढूंढना चाहिए जो अन्य चीजों के साथ CanExecute को उचित रूप से लागू करता है।

+0

सिंच एक कमांडस्क्वाइड बूल प्रॉपर्टी में अपने अपरिवर्तित परीक्षण को पकाकर रिलेकॉमैंड के साथ एक कदम आगे चला जाता है। आपकी पोस्ट यह लागू करने में सहायक है कि सेटक्लोस अभी भी दिन के अंत में एक संपत्ति सेटर है, भले ही यह सामान्य सामान्य सी # प्रॉपर्टी सेटर्स की तरह न लगे! यह उन चीजों में से एक है जो मैं नहीं देख रहा था और अभी तक मेरे लिए डीपी/संलग्न व्यवहार के बारे में सहज नहीं है। चीयर्स – Berryl

+0

हाँ। संकलित होने पर, उन स्थिर गेट/सेट विधियों को बुलाया जाता है। डीपी के साथ वही बात: यह संपत्ति रैपर को छोड़ देती है और 'निर्भरता' पर 'SetValue'/'GetValue' को सीधे कॉल करती है। सिंच में इसके बारे में सुनकर अच्छा लगा। यह वह नहीं है जिसे मैंने अभी तक देखा है। –

3

DependencyProperty बदल रहा है और मेरे लिए 'असंभव निर्भरता' की तरह अपने स्वयं के दिखता है पर मूल्य बलात्कार। खिड़की के संदर्भ में चीजों को और भी मुश्किल बनाता है। मुझे लगता है मैं Humble Object pattern यहाँ के साथ जाना चाहता हूँ ...

+0

मैं वास्तव में इस मामले में खिड़की के साथ रह सकता हूं, लेकिन यह एक दिलचस्प लिंक है। क्या आप इस मामले में आप नम्र ऑब्जेक्ट पैटर्न को कैसे लागू करेंगे? चीयर्स – Berryl

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