Perché Mockito non simula i metodi statici?

Ho letto alcuni thread qui sui metodi statici, e penso di capire i problemi che possono causare l’abuso / uso eccessivo di metodi statici. Ma non ho davvero capito perché è difficile prendere in giro metodi statici.

So che altri sistemi di derisione, come PowerMock, possono farlo, ma perché Mockito non può?

Ho letto questo articolo , ma l’autore sembra essere religioso contro la parola ” static , forse è la mia scarsa comprensione.

Una spiegazione / collegamento facile sarebbe grandiosa.

Penso che la ragione potrebbe essere che le librerie di oggetti mock tipicamente creano mock creando dynamicmente le classi in fase di runtime (usando cglib ). Ciò significa che implementano un’interfaccia in fase di esecuzione (è ciò che fa EasyMock se non mi sbaglio), o ereditano dalla class alla simulazione (questo è ciò che fa Mockito se non mi sbaglio). Entrambi gli approcci non funzionano per i membri statici, poiché non è ansible sovrascriverli utilizzando l’ereditarietà.

L’unico modo per simulare la statica è modificare il codice byte di una class in fase di runtime, che suppongo sia un po ‘più complicato dell’ereditarietà.

Questa è la mia ipotesi, per quello che vale …

Se hai bisogno di prendere in giro un metodo statico, è un forte indicatore di un cattivo design. Di solito, prendi in giro la dipendenza della tua class sotto test. Se il sottotest della class fa riferimento a un metodo statico, ad esempio java.util.Math # sin, significa che la class sotto test ha esattamente bisogno di questa implementazione (ad esempio, precisione e velocità). Se vuoi astrarre da un’implementazione sinusale, probabilmente hai bisogno di un’interfaccia (vedi dove andrà a finire)?

Penso seriamente che sia l’odore del codice se hai bisogno di prendere in giro anche metodi statici.

  • Metodi statici per accedere a funzionalità comuni? -> Usa un’istanza singleton e inseriscila
  • Codice di terze parti? -> Avvolgilo nella tua interfaccia / delegato (e se necessario rendilo anche singleton)

L’unica volta che questo mi sembra eccessivo, sono libs come Guava, ma non dovresti prenderti gioco di questo tipo perché è parte della logica … (cose come Iterables.transform (..))
In questo modo il tuo codice rimane pulito, puoi prendere in giro tutte le tue dipendenze in modo pulito e hai un livello anti corruzione contro le dipendenze esterne. Ho visto PowerMock in pratica e tutte le classi di cui avevamo bisogno erano mal progettate. Anche l’integrazione di PowerMock a volte ha causato seri problemi
(ad es. https://code.google.com/p/powermock/issues/detail?id=355 )

PS: anche le stesse prese per i metodi privati. Non penso che i test dovrebbero conoscere i dettagli dei metodi privati. Se una class è così complessa da tentare di prendere in giro metodi privati, è probabilmente un segnale per dividere quella class …

Mockito restituisce oggetti ma statici significa “livello di class, non a livello di object”. Quindi mockito fornirà un’eccezione di puntatore nullo per statico.

In alcuni casi, i metodi statici possono essere difficili da testare, specialmente se devono essere presi in giro, motivo per cui la maggior parte dei framework di simulazione non li supporta. Ho trovato questo post sul blog molto utile per determinare come simulare metodi e classi statici.