Domanda

Sono nuovo a deridere oggetti, ma capisco che devo avere le mie classi implementare interfacce per deriderli.

Il problema che sto riscontrando è che nel mio livello di accesso ai dati voglio avere metodi statici, ma non riesco a inserire un metodo statico in un'interfaccia.

Qual è il modo migliore per aggirare questo? Dovrei semplicemente usare metodi di istanza (che sembra sbagliato) o c'è un'altra soluzione?

È stato utile?

Soluzione

Vorrei usare un modello a oggetti metodo. Avere un'istanza statica di questo e chiamarla nel metodo statico. Dovrebbe essere possibile effettuare una sottoclasse per i test, a seconda del framework di derisione.

vale a dire. nella tua classe con il metodo statico hanno:

private static final MethodObject methodObject = new MethodObject();

public static void doSomething(){
    methodObject.doSomething();
}

e l'oggetto del metodo può essere molto semplice, facilmente testabile:

public class MethodObject {
    public void doSomething() {
        // do your thang
    }
}

Altri suggerimenti

Sì, usi metodi di istanza. I metodi statici sostengono sostanzialmente: "C'è un modo per realizzare questa funzionalità: non è polimorfico." La derisione si basa sul polimorfismo.

Ora, se i tuoi metodi statici logicamente non si preoccupano dell'implementazione che stai utilizzando, potrebbero essere in grado di prendere le interfacce come parametri o forse funzionare senza interagire con lo stato, ma altrimenti dovresti usare le istanze (e probabilmente iniezione di dipendenza per collegare tutto insieme).

Ho trovato un blog via google con alcuni ottimi esempi su come farlo:

  1. La classe refactor è una classe di istanza e implementa un'interfaccia.

    Hai già dichiarato di non volerlo fare.

  2. Utilizza una classe di istanza wrapper con delegati per i membri di classi statiche

    In questo modo è possibile simulare un'interfaccia statica tramite delegati.

  3. Utilizza una classe di istanza wrapper con membri protetti che chiamano la classe statica

    Questo è probabilmente il più facile da deridere / gestire senza refactoring in quanto può essere ereditato ed esteso.

Potresti provare a provare ad un punto di partenza troppo profondo. Non è necessario creare un test per testare ogni singolo metodo; i metodi privati ??e statici devono essere testati chiamando i metodi pubblici che quindi a loro volta chiamano quelli privati ??e statici.

Quindi supponiamo che il tuo codice sia così:

public object GetData()
{
 object obj1 = GetDataFromWherever();
 object obj2 = TransformData(obj1);
 return obj2;
} 
private static object TransformData(object obj)
{
//Do whatever
}

Non è necessario scrivere un test sul metodo TransformData (e non è possibile). Scrivi invece un test per il metodo GetData che verifica il lavoro svolto in TransformData.

Utilizza i metodi di istanza ove possibile.

Usa Func [T, U] pubblico statico (riferimenti a funzioni statiche che possono essere sostituite con funzioni simulate) in cui i metodi di istanza non sono possibili.

Una soluzione semplice è consentire di modificare l'implementazione della classe statica tramite un setter:

class ClassWithStatics {

  private IClassWithStaticsImpl implementation = new DefaultClassWithStaticsImpl();

  // Should only be invoked for testing purposes
  public static void overrideImplementation(IClassWithStaticsImpl implementation) {
     ClassWithStatics.implementation = implementation;
  }

  public static Foo someMethod() {
    return implementation.someMethod();
  }

}

Quindi, nella configurazione dei test, chiami overrideImplementation con un'interfaccia derisa. Il vantaggio è che non è necessario modificare i client della propria classe statica. L'aspetto negativo è che probabilmente avrai un piccolo codice duplicato, perché dovrai ripetere i metodi della classe statica e la sua implementazione. Ma a volte i metodi statici possono utilizzare un'interfaccia più chiara che fornisce funzionalità di base.

Il problema che hai è quando stai usando codice di terze parti e viene chiamato da uno dei tuoi metodi. Quello che abbiamo finito è avvolgerlo in un oggetto e chiamare passarlo con dep inj, e quindi il tuo test unitario può prendere in giro un metodo statico di terze parti per chiamare il setter con esso.

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