Por alguna razón, necesito un hijo primero ClassLoader
. Tal ClassLoader
no existe en el JDK, así que lo estoy escribiendo. Dado que este es un componente clave de mi caso de uso, me gustaría que fuera sometido a pruebas exhaustivas. Para garantizar que no se cambie sin romper el comportamiento, quiero ser extremadamente minucioso y probar todo lo que se pueda probar automáticamente.
Entonces, ¿cómo puedo probarlo? ¿Cómo debo hacer mi prueba de unidad básica? Estoy atascado en cuanto a dónde comenzar (especialmente porque hay al menos una super
llamada en cada método) y estoy buscando algunas pautas para comenzar.
Mi idea principal es la siguiente. ¿Hay algo malo en ello?
/src/main/resources/parent.jar
child.jar
El archivo parent.jar
contiene una clase com.example.Example
que es un Supplier
retorno básico "parent"
. El archivo child.jar
contiene una clase com.example.Example
que es un Supplier
retorno básico "child"
.
Estaría creando un estándar URLClassLoader
para parent.jar
, y usaría mi costumbre ClassLoader
para cargar child.jar
. Luego cargaría la clase com.example.Example
y verificaría que en realidad regrese en "child"
lugar de "parent"
.
Se piensan casos de prueba más complejos, pero solo necesito una confirmación para comenzar: ¿es esto suficiente para la prueba básica? ¿Es esto realmente lo que debería probar en mis pruebas unitarias? Si no, ¿qué es?
Estoy bastante seguro de que el código no es necesario para esto, pero en caso de que tenga curiosidad o lo que sea, aquí está.
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);
}
}
fuente
Respuestas:
Por supuesto, no sé mucho sobre ClassLoaders o Java para ese asunto, pero tendría problemas para que la unidad lo pruebe. Una de las razones es, como usted dice, que su clase hereda de
URLClassLoader
. Incluso si pudiéramos burlarnos de la superclase de alguna manera, no confiaría mucho en las pruebas que verifican que mi implementación hace lo que se pretende hacer.Entonces, para lo que vale, me inclinaría por escribir una prueba más integrada aquí: tal vez tener algunas carpetas "fixture" que contengan ejemplos como el que usted presentó:
Eso me llevaría a escribir una prueba para cada uno de esos casos y "usar" las clases padre / hijo de una manera muy simple solo para verificar que se cargó o no se pudo cargar como esperaba.
fuente