2010-02-19 21 views
7

Genelde ekli davranışları güçlendiriyorum ve bir birim testi nasıl yazılacağını görmek için bir kayıp yaşıyorum.birim ekli bir davranışı test edin wpf

Sacha Barber's Cinch çerçevesinden eklenmiş bir davranışla bir pencerenin kapatılmasına izin veren bazı kodları aşağıya yapıştırdım. Bir şekilde bana bunun için örnek bir birim testi gösterebilir mi?

Teşekkürler!
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 

cevap

5

Büyük olasılıkla bir DelegateCommand veya RelayCommand kullanarak sizin ICommand bir lambda kullanmak düşünüyorum. Bunların her yerinde birden fazla uygulama var ve Cinch benzer bir şeylere sahip olabilir. (Üretim kullanıma yönelik değildir örnek olarak,) Gerçekten basit sürüm:

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 
} 

Sonra test vücut böyle bir şey olabilir:

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); 

Bu aşırı basitleştirilmiş bir örnektir. Yapmak isteyeceğiniz başka testler de vardır, bu durumda'un diğer uygulamalarının yanı sıra CanExecute'u da düzgün bir şekilde uygulayan bir uygulama oluşturmalı veya bulmalısınız.

+0

cinch, bir CommandSucceeded bool özelliğine dönüştürülmüş testinizi yaparak RelayCommand ile bir adım daha ileri gider. Yayınınız, daha basit normal C# özellik belirteçleri gibi görünmese bile, günün sonunda SetClose'un hala bir özellik belirleyici olduğunu desteklemede yardımcı oluyor! Bu benim görmediğim ve DP/iliştirilmiş davranış hakkında henüz sezgisel olmayan şeylerden biri. Şerefe – Berryl

+0

Yep. Derlendiğinde, bu statik Get/Set yöntemleri denir. DP'lerle aynı şey: özellik sarıcısını atlar ve doğrudan 'DependencyObject' üzerinde 'SetValue' /' GetValue' olarak adlandırır. Cinch'de bunu duymak güzel. Henüz gözetlemediğim bir şey değil. –

3

DependencyProperty değişen ve benim için 'İmkansız bağımlılıklar' gibi kendi görüntüsü üzerinde değer dayatması. Pencereye referansla, işleri daha da zorlaştırıyor. Ben burada ... Humble Object pattern ile gitmek istiyorum

+0

Aslında bu durumda pencereyle yaşayabilirim, ancak bu ilginç bir bağlantıdır. Bu durumda Humble Object Pattern'i nasıl uygulayacağınızı gösterebilir misiniz? Cheer – Berryl