Come testare l'unità ClassLoader personalizzato?

8

Per alcuni motivi, ho bisogno di un ClassLoader prima del bambino. Tale ClassLoader non esiste nel JDK, quindi lo sto scrivendo. Poiché questo è un componente chiave del mio caso d'uso, mi piacerebbe che fosse strongmente testato. Per garantire che non venga modificato senza interrompere il comportamento, voglio essere estremamente accurato e testare tutto ciò che è testabile automaticamente.

Quindi, come posso testarlo? Come dovrei fare il mio test unitario di base? Sono un po 'bloccato da dove cominciare (soprattutto dal momento che c'è almeno una chiamata di super in ogni metodo) e sto cercando alcune linee guida per iniziare.

La mia idea principale è la seguente. C'è qualcosa di sbagliato in questo?

/src/main/resources/parent.jar
                    child.jar

Il file parent.jar contiene una classe com.example.Example che è una base Supplier che restituisce "parent" . Il file child.jar contiene una classe com.example.Example che è una base Supplier che restituisce "child" .

Creo un URLClassLoader standard per parent.jar e userei il mio ClassLoader personalizzato per caricare child.jar . Quindi caricarei la classe com.example.Example e verifica che stia effettivamente restituendo "child" anziché "parent" .

Si pensa a casi di test più complessi, ma ho solo bisogno di una conferma per iniziare: è sufficiente per il test di base? È davvero questo che dovrei provare nei miei test unitari? In caso contrario, che cos'è?

Sono abbastanza sicuro che il codice non sia necessario per questo, ma nel caso sei curioso o altro, eccolo.

import java.io.*;
import java.net.*;
import java.util.*;

class ChildFirstClassLoader extends URLClassLoader {

  ChildFirstClassLoader(ClassLoader parent) {
    super(new URL[0], parent);
  }

  @Override
  // Make this method available in this package.
  protected void addURL(URL url) {
    super.addURL(url);
  }

  @Override
  protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
    synchronized (getClassLoadingLock(name)) {
      Class<?> c = findLoadedClass(name);
      if (c == null) {
        try {
          c = findClass(name);
        } catch (ClassNotFoundException ignore) {
          c = super.loadClass(name, resolve);
        }
      }
      if (resolve) {
        resolveClass(c);
      }
      return c;
    }
  }

  @Override
  public URL getResource(String name) {
    URL url = findResource(name);
    if (url == null) {
      url = super.getResource(name);
    }
    return url;
  }

  @Override
  public Enumeration<URL> getResources(String name) throws IOException {
    List<URL> urls = new ArrayList<>();
    urls.addAll(Collections.list(findResources(name)));
    urls.addAll(Collections.list(super.getResources(name)));
    return Collections.enumeration(urls);
  }
}
    
posta Olivier Grégoire 27.09.2016 - 10:52
fonte

1 risposta

2

So how can I test it? How should I make my basic unit test? I'm kind of stuck as to where to start (especially since there's at least one super call in each method) and I'm looking for some guidelines to start.

Certo, non so molto di ClassLoaders o Java, ma avrei difficoltà a testare questa unità. Uno dei motivi è che, come affermi, la tua classe eredita da URLClassLoader . Anche se potessimo prendere in giro la superclasse in qualche modo, non avrei molta fiducia nei test per verificare che la mia implementazione faccia ciò che è destinato a fare.

Quindi, per quello che vale, mi piacerebbe scrivere qui un test più integrato: magari avere qualche cartella "fixture" contenente esempi come quello che hai presentato:

  • Infissi
    • CanSuccessfullyLoad
      • parent.jar
      • child.jar
    • ThrowsAnErrorOnLoad
      • justparent.jar

Ciò comporterebbe che io scrivessi un test per ciascuno di questi casi e "usassi" le classi genitore / figlio in un modo molto semplice solo per verificare che fosse caricato o non fosse riuscito a caricare come mi aspettavo.

    
risposta data 02.08.2017 - 21:21
fonte

Leggi altre domande sui tag