Aus bestimmten Gründen brauche ich zuerst ein Kind ClassLoader
. Solches ClassLoader
gibt es im JDK nicht, also schreibe ich es. Da dies eine Schlüsselkomponente meines Anwendungsfalls ist, möchte ich, dass er intensiv getestet wird. Um sicherzustellen, dass es nicht geändert wird, ohne das Verhalten zu beeinträchtigen, möchte ich äußerst gründlich sein und alles testen, was automatisch getestet werden kann.
Wie kann ich es testen? Wie soll ich meinen Basis-Unit-Test machen? Ich bin mir nicht sicher, wo ich anfangen soll (zumal es super
in jeder Methode mindestens einen Aufruf gibt) und suche nach Richtlinien, um zu beginnen.
Meine Hauptidee ist die folgende. Stimmt etwas nicht?
/src/main/resources/parent.jar
child.jar
Die Datei parent.jar
enthält eine Klasse, com.example.Example
die eine grundlegende Supplier
Rückgabe darstellt "parent"
. Die Datei child.jar
enthält eine Klasse, com.example.Example
die eine grundlegende Supplier
Rückgabe darstellt "child"
.
Ich würde einen Standard URLClassLoader
für erstellen parent.jar
und meine Gewohnheit ClassLoader
zum Laden verwenden child.jar
. Dann würde ich die Klasse laden com.example.Example
und überprüfen, ob sie tatsächlich zurückkehrt, "child"
anstatt "parent"
.
Über komplexere Testfälle wird nachgedacht, aber ich brauche nur eine Bestätigung, um zu beginnen: Reicht dies für den Basistest aus? Sollte ich das wirklich in meinen Unit-Tests testen? Wenn nicht, was ist das?
Ich bin mir ziemlich sicher, dass der Code dafür nicht benötigt wird, aber falls Sie neugierig sind oder was auch immer, hier ist es.
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);
}
}
quelle
Antworten:
Zugegeben, ich weiß nicht viel über ClassLoaders oder Java, aber ich hätte Probleme, dies zu testen. Einer der Gründe ist, wie Sie sagen, dass Ihre Klasse von erbt
URLClassLoader
. Selbst wenn wir die Oberklasse irgendwie verspotten könnten, hätte ich nicht viel Vertrauen in die Tests, die bestätigen, dass meine Implementierung das tut, was beabsichtigt ist.Für das, was es wert ist, würde ich mich darauf stützen, hier einen stärker integrierten Test zu schreiben: Vielleicht ein paar "Fixture" -Ordner mit Beispielen wie dem, den Sie vorgestellt haben:
Das würde dazu führen, dass ich für jeden dieser Fälle einen Test schreibe und die Eltern / Kind-Klassen auf sehr einfache Weise "verwende", um zu überprüfen, ob sie geladen wurden oder nicht wie erwartet geladen wurden.
quelle