Come posso prendere in giro questa architettura?

1

Questa non è una domanda molto generica, quindi potrebbe non essere esattamente appropriata qui, ma potrei sicuramente usare un suggerimento se ne hai uno:

Ho un oggetto contenente un dizionario digitato da un enum, qualcosa del genere:

namespace Application
{
    public enum Material { H20, CO2, Na }
    public class Container
    {
        private Dictionary<Material, ChemicalComponent> dic;
        public Container(Dictionary<Material, ChemicalComponent> d)
        {
            dic = d;
        }
    }
}

Ora voglio creare un MockContainer e un MockMaterial, ma non riesco a capire come far funzionare tutto insieme. Il seguente codice, ad esempio, non funziona (vedi commento):

using Application;  
namespace UnitTesting
{
    public enum mockMaterial { mock1, mock2, mock3 }
    public class mockContainer : Container
    {
        public mockContainer(Dictionary<mockMaterial, ChemicalComponent> d)
            : base(d) // compiler error: the base constructor "has some invalid arguments"
        {
        }
    }
}

Inizialmente avevo sperato di estendere l'enum materiale all'interno dello spazio dei nomi di UnitTesting; quindi potrei semplicemente usare il dizionario del contenitore, ma con chiavi diverse. Ma ovviamente non è legale in C #. C'è un modo non-kludgy per sovraccaricare o iniettare un dizionario con le chiavi di enum finto?

Aggiornamento: Un'opzione è di cambiare la definizione del dizionario in questo modo:

private Dictionary<Enum, ChemicalComponent> dic;

(ad esempio, cambia il tipo di chiave in Enum in tutto il codice). Questo funziona (ad esempio, elimina l'errore del compilatore), ma questa soluzione sacrifica la chiarezza e la sicurezza del tipo. (Non è più chiaro quale sia il significato della chiave).

Aggiornamento n. 2: Diverse persone hanno raccomandato di creare un'interfaccia per Container. Ma questo manca il punto. Il contenitore stesso non è poi così complesso. Ma il ChemicalComponents che è memorizzato in esso è molto complesso. Devo simulare quelli nei miei test di unità, ma non so come farlo senza estendere l'enumerazione che funge da chiave.

    
posta kmote 17.10.2014 - 22:35
fonte

3 risposte

4

I now want to create a MockContainer and a MockMaterial, but I can't figure out how to make it all work together.

Perché?

Voglio dire, lo scopo degli oggetti test (mock, falsi, stub, ecc.) è quello di rimuovere alcune dipendenze nel codice in modo da poter testare ignorando la dipendenza. Material è un enum. Non è una sorta di dipendenza che sta per infrangere i test. Fare un qualche trucco inglorioso è più probabile che interrompa i test (e il tuo codice di produzione).

Se vuoi un contenitore fittizio (sto assumendo che il tuo contenitore sia più che un alias per Dictionary<Material, ChemicalComponent> ), allora dovresti fornire un'interfaccia al contenitore e deriderlo.

E ricorda:

  • Se il codice è difficile da testare, è probabilmente difficile da usare (vedi, mancanza di interfaccia che lo rende inflessibile per una diversa implementazione).
  • I test sono lì per servirti, non viceversa. Non fare le cose alla cieca perché dovresti . Falli perché ti semplificano la vita.
risposta data 17.11.2014 - 02:00
fonte
0

Potresti rendere Container una classe generica con un parametro di tipo, vincolato ad essere un enum.

La tua simulazione non è stata in grado di creare una sottoclasse in questo modo, quindi è necessario creare un'interfaccia.

    
risposta data 18.10.2014 - 01:44
fonte
0

Non vale la pena di deridere un enum, non guadagni nulla con questo. Non ti deriderebbe System.Int32, vero? Per quanto riguarda il mocking container, vorrei creare un'interfaccia e quindi puoi prendere in giro l'implementazione di tale interfaccia.

    
risposta data 17.11.2014 - 02:00
fonte

Leggi altre domande sui tag