Domanda

Sono ancora Grokking comportamenti collegati in generale, e sono in perdita per vedere come scrivere uno unit test per uno.

Ho incollato un certo codice di seguito dal quadro Cinch di Sacha Barber, che permette una finestra da chiudere mediante un comportamento allegato. Può somewone mostrarmi un test ad esempio un'unità per questo?

Grazie!
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
È stato utile?

Soluzione

Si sarebbe probabilmente utilizzare un lambda nella vostra ICommand utilizzando un DelegateCommand o un RelayCommand. Più implementazioni di questi esiste in tutto il luogo e Cinch possono avere qualcosa di simile. Versione molto semplice (ad esempio, non è inteso per la produzione):

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
}

Poi il corpo di prova potrebbe essere simile a questo:

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

Questo è un esempio troppo semplificata. Ci sono naturalmente altri test si desidera eseguire, nel qual caso è necessario creare o trovare un'implementazione più completa di DelegateCommand che anche implementa correttamente CanExecute, tra le altre cose.

Altri suggerimenti

DependencyProperty che cambia e il valore di coercizione sui loro sguardi, come 'Dipendenze impossibili' per me. Avendo riferimento alla finestra ci rende le cose ancora più complicato. Penso che mi piacerebbe andare con Humble qui ...

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top