Voltei. Mas para perguntar, não responder.
Explicá-los-ei. Preciso executar um teste JUnit (4.5) em um método qualquer chamado em uma aplicação web. Porém a classe JUnit não consta na mesma biblioteca de classes ou fontes desta aplicação web, mas sim em outro diretório. Desta forma, escrevi uma classe com método auxiliar que carregasse uma instância desta classe JUnit externa e me retornasse um Class. De posse do Class deste JUnit, posso executá-lo com JUnitCore.runClasses( Class <?>… classes ). Bom, vamos aos códigos:
Classe e método que me retornam o Class de uma classe JUnit:
[code]
package pucrs.tcc.core;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
public class TCClassLoader {
private static final TCClassLoader instance = new TCClassLoader();
private TCClassLoader() { }
public Class <?> loadClass( String name, String testClassesPath ) {
try {
File file = new File( testClassesPath );
URL myUrl = file.toURL();
URL urls [] = new URL[] { myUrl };
ClassLoader classLoader = new URLClassLoader( urls );
return classLoader.loadClass( name );
} catch ( MalformedURLException e ) {
e.printStackTrace();
} catch ( ClassNotFoundException e ) {
e.printStackTrace();
}
return null;
}
public static TCClassLoader getInstance() {
return instance;
}
}[/code]
Método que usa TCClassLoader.loadClass() e executa o JUnit (por ex, um doGet()):
protected void doGet( HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException {
Class <?> c = TCClassLoader.getInstance().loadClass( "pucrs.tcc.test.FooTest", "/Users/matheusdutrademoura/Documents/workspace/Tests/bin" );
Result result = JUnitCore.runClasses( c );
List <Failure> failures = result.getFailures();
for ( Failure f : failures ) {
System.out.println( f.getTestHeader() );
System.out.println( f.getMessage() );
System.out.println( f.getException() );
System.out.println( f.getTrace() );
}
}
A classe JUnit:
[code]package pucrs.tcc.test;
import static org.junit.Assert.assertTrue;
import org.junit.Test;
public class FooTest {
@Test public void fTest() {
assertTrue( false );
}
@Test public void gTest() {
assertTrue( true );
}
}[/code]
Agora o problema: Se eu executar este mesmíssimo código, com o mesmíssimo junit-4.5.jar em uma aplicação standalone, funciona perfeitamente. Porém, se eu tento fazê-lo por uma aplicação web, estoura a seguinte exception ao chamar JUnitCore.runClasses():
initializationError(pucrs.tcc.test.FooTest)
No runnable methods
java.lang.Exception: No runnable methods
java.lang.Exception: No runnable methods
at org.junit.runners.BlockJUnit4ClassRunner.validateInstanceMethods(BlockJUnit4ClassRunner.java:154)
at org.junit.runners.BlockJUnit4ClassRunner.collectInitializationErrors(BlockJUnit4ClassRunner.java:112)
at org.junit.runners.ParentRunner.validate(ParentRunner.java:253)
at org.junit.runners.ParentRunner.<init>(ParentRunner.java:55)
at org.junit.runners.BlockJUnit4ClassRunner.<init>(BlockJUnit4ClassRunner.java:56)
at org.junit.internal.builders.JUnit4Builder.runnerForClass(JUnit4Builder.java:13)
at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:57)
at org.junit.internal.builders.AllDefaultPossibilitiesBuilder.runnerForClass(AllDefaultPossibilitiesBuilder.java:29)
at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:57)
at org.junit.runners.model.RunnerBuilder.runners(RunnerBuilder.java:93)
at org.junit.runners.model.RunnerBuilder.runners(RunnerBuilder.java:84)
at org.junit.runners.Suite.<init>(Suite.java:66)
at org.junit.runner.Request.classes(Request.java:68)
at org.junit.runner.JUnitCore.run(JUnitCore.java:107)
at org.junit.runner.JUnitCore.runClasses(JUnitCore.java:66)
at com.foo.FooServlet.doGet(FooServlet.java:24)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:690)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:286)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
at java.lang.Thread.run(Thread.java:613)
Na aplicação web tudo funciona, com exceção da chamada ao JUnit em si. Posso acessar qualquer coisa da classe retornada via reflection tranqüilamente. Já pesquisei sobre isso no Google (por 2 dias inteiros!). Se eu postei o problema aqui é pq definitivamente não sei mais o que fazer :sad: