Search code examples
javaunit-testingtestngdynamic-class-creation

How can I test a .class file was created?


I want to unit test my code which will have to create a .java file compile it and then the corresponding .class file should be created.

How can I create the test to see if the ".class" file is created? I have added test already for its existence, now I'm trying to test the file is a valid class file.

I tried

 try  {
      Class.forName("Hello");
      throw AssertError();
 } catch( ClassNotFoundException e ) {
 }

 program.createClass();
 Class.forName("Hello");

But I don't really know how to dynamically add the path where the file is created to the classpath.

EDIT

URL Class loaded does the work.

This is how my test looks like now.

@Test
void testHello() throws MalformedURLException, ClassNotFoundException {
    URL[] url = {
            new URL("file:/home/oreyes/testwork/")
    };

    try {
        new URLClassLoader(url).loadClass("Hello");
        throw new AssertionError("Should've thrown ClassNotFoundException");
    } catch ( ClassNotFoundException cnfe ){

    }
    c.process();
    new URLClassLoader(url).loadClass("Hello");
}

Solution

  • Use a new instance of an URLClassLoader, pointing to the root folder where you created the target class file. Then, use the Class.forName(String,ClassLoader); method with the dynamically created URLClassLoader to load the new class.

    To show that it works, the following test case will create a source file, write some Java code in there and compile it using the Java 6 ToolProvider interfaces. Then, it will dynamically load the class using an URLClassLoader and invoke a reflective call to its class name to verify it's really this class which has been generated on the fly.

    @Test
    public void testUrlClassLoader() throws Exception {
        Random random = new Random();
        String newClassName = "Foo" + random.nextInt(1000);
        JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
        StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);
        List<File> files = new ArrayList<File>();
        File sourceFolder = new File(".");
        File sourceFile = new File(sourceFolder, newClassName + ".java");
        FileWriter fileWriter = new FileWriter(sourceFile);
        fileWriter.write("public class " + newClassName + " { { System.out.println(\""
                + newClassName + " loaded\"); }}");
        fileWriter.close();
        files.add(sourceFile);
        Iterable<? extends JavaFileObject> compilationUnits1 = fileManager
                .getJavaFileObjectsFromFiles(files);
        compiler.getTask(null, fileManager, null, null, null, compilationUnits1).call();
        fileManager.close();
    
        URL url = sourceFolder.toURI().toURL();
        URLClassLoader urlClassLoader = new URLClassLoader(new URL[] { url });
        Object newInstance = urlClassLoader.loadClass(newClassName).newInstance();
        assertEquals(newClassName, newInstance.getClass().getName());
    }