MVP Passive View - Dipendenza iniezione - Modello di fabbrica - Sta testando il comportamento mentre ignora lo stato sufficiente?

2

Sto scrivendo un'applicazione utilizzando il modello di visualizzazione passiva Model / View / Presenter.

Ho una vista che contiene più elementi in una lista. Il mio modello è di tipo AudioDrama . Per filtrare quell'elenco ho classi che implementano l'interfaccia IAudioDramaFilter .

public interface IAudioDramaFilter
{
    EAudioDramaFilterMode FilterMode { get; }
    IEnumerable<AudioDrama> Filter(IEnumerable<AudioDrama> audioDramas);
}

Come puoi vedere dall'enum FilterMode ho diverse implementazioni di quell'interfaccia filtro.

public enum EAudioDramaFilterMode
{
    All,
    MainsOnly,
    FavoritesOnly,
    UnheardOnly,
    SpecialsOnly
}

La mia vista passiva ha più eventi che si alzano non appena l'utente richiede / fa clic su un nuovo filtro. Cioè l'utente potrebbe fare clic sul pulsante Preferiti e quindi viene generato l'evento FavoritesOnlyClicked .

Il mio relatore per quella vista si iscrive a questo tipo di eventi:

_audioDramaListView.FavoritesOnlyClicked += OnFilterChanged(EAudioDramaFilterMode.FavoritesOnly);

In quel metodo OnFilterChanged ho impostato il campo filtro nel mio presentatore sul filtro corretto creando un nuovo filtro tramite la factory che viene data come dipendenza dal mio relatore.

private EventHandler OnFilterChanged(EAudioDramaFilterMode filterMode)
    {
        return (sender, args) =>
        {
            _audioDramaFilter = _audioDramaFilterFactory.Create(filterMode);
            UpdateView();
        };
    }

Ora voglio testare tutta la logica. Dato che do la fabbrica al mio presentatore tramite l'iniezione di dipendenza, posso semplicemente deriderlo e verificare che venga chiamato il metodo corretto Create , cioè:

 _listView.Raise(x => x.FavoritesOnlyClicked += null, this, EventArgs.Empty);

 _filterFactory.Verify(x => x.Create(EAudioDramaFilterMode.FavoritesOnly), Times.Once);

Funziona alla grande. Il mio problema ora è che controllo solo se è stato chiamato il metodo factory corretto. Ma non ho mai testato se il valore fosse effettivamente impostato sul campo privato _audioDramaFilter .

Devo rendere il campo internal solo per testarlo? Non ferirebbe il mio incapsulamento? C'è qualche difetto di progettazione che non vedo? Perché sarebbe sempre il caso non appena utilizzo una fabbrica invece di una dipendenza statica. Ma voglio essere in grado di cambiare l'implementazione in modo dinamico ...

Scrivo la domanda perché ora è successo un'altra volta: ho implementato una sorter con una SorterFactory ...

Grazie in anticipo per qualsiasi aiuto / idee!

    
posta selmaohneh 09.10.2018 - 12:04
fonte

1 risposta

2

Should I make the field internal just to test that?

No.

L'approccio abituale è concentrarsi sui comportamenti osservabili, piuttosto che sui dettagli di implementazione.

In questo caso, come sapresti che il filtro è stato assegnato? Probabilmente perché la modifica del filtro cambierebbe anche l'elenco osservabile di AudioDrama . Cioè, dopo tutto quello che ti interessa davvero - il fatto che tu abbia usato uno factory per creare la dipendenza piuttosto che farlo all'interno della classe stessa di solito non è interessante.

Può essere d'aiuto pensare al tuo sistema sotto test come una funzione , che prende come argomento un elenco non filtrato e un metodo filterMode, e restituisce un elenco filtrato. Quindi scopri l'implementazione di quella funzione, che sarà un po 'di orchestrazione del filtro, della fabbrica, e qualsiasi altro pezzo e pezzo contribuisca alla matematica.

    
risposta data 09.10.2018 - 18:45
fonte

Leggi altre domande sui tag