Por algumas razões, preciso de um filho primeiro ClassLoader
. Isso ClassLoader
não existe no JDK, então estou escrevendo. Como esse é um componente-chave do meu caso de uso, eu gostaria que fosse testado intensamente. Para garantir que não seja alterado sem interromper o comportamento, quero ser extremamente completo e testar tudo o que é testável automaticamente.
Então, como posso testá-lo? Como devo fazer meu teste de unidade básico? Estou meio que confuso sobre onde começar (principalmente porque há pelo menos uma super
chamada em cada método) e estou procurando algumas diretrizes para começar.
Minha idéia principal é a seguinte. Há algo de errado com isso?
/src/main/resources/parent.jar
child.jar
O arquivo parent.jar
contém uma classe com.example.Example
que é um Supplier
retorno básico "parent"
. O arquivo child.jar
contém uma classe com.example.Example
que é um Supplier
retorno básico "child"
.
Eu estaria criando um padrão URLClassLoader
para parent.jar
e usaria meu costume ClassLoader
para carregar child.jar
. Então eu carregava a classe com.example.Example
e verificava se ela realmente estava retornando em "child"
vez de "parent"
.
Casos de teste mais complexos são pensados, mas eu só preciso de uma confirmação para começar: isso é suficiente para o teste básico? É realmente isso que eu deveria testar nos meus testes de unidade? Se não, o que é?
Tenho certeza de que o código não é necessário para isso, mas caso você esteja curioso ou algo assim, aqui 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);
}
}
fonte
Respostas:
É verdade que não conheço muito sobre ClassLoaders ou Java, mas teria problemas ao testar isso. Um dos motivos é, como você declara, sua classe herdada
URLClassLoader
. Mesmo que pudéssemos zombar da superclasse de alguma forma, eu não confiaria muito nos testes para verificar se minha implementação faz o que se pretende fazer.Então, pelo que vale a pena, gostaria de escrever um teste mais integrado aqui: talvez tenha algumas pastas "fixture" contendo exemplos como o que você apresentou:
Isso resultaria em mim escrevendo um teste para cada um desses casos e "usando" as classes pai / filho de uma maneira muito simples, apenas para verificar se ele carregou ou falhou ao carregar como eu esperava.
fonte