0

I have a method that generates java class and writes to a .java file. How can write a unit test on this method to make sure the format of the string this is writing to the file is in standard java class format.

Ex: I should check if it has a package declaration Should check if package is before class declaration open and close braces etc...

Rookie
  • 33
  • 4

2 Answers2

0

Here's a method which can be used to find the compilation errors in a Java files, if there are no errors generated then it's a perfectly valid Java Class.

import java.io.File;
import java.io.IOException;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import javax.tools.Diagnostic;
import javax.tools.DiagnosticCollector;
import javax.tools.JavaCompiler;
import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;

public class TestMain {

    public static void main(String[] args) {
        List<File> sourceList = Arrays.asList(Paths.get("MyJavaClass.java").toFile());
        List<String> errorList = new TestMain().compile(sourceList);
        if(errorList.size() == 0) {
            System.out.println("No error found, perfectly valid java class");
        } else {
            errorList.forEach(System.out::println);
        }
    }

    public List<String> compile (List<File> javaFileList) {
        System.out.println("Started compilation");
        List<String> errorList = new ArrayList<String>();
        JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();

        DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<JavaFileObject>();
        StandardJavaFileManager fileManager = compiler.getStandardFileManager(
                diagnostics, null, null);

        Iterable<? extends JavaFileObject> compilationUnits = fileManager
                .getJavaFileObjectsFromFiles(javaFileList);
        compiler.getTask(null, fileManager, diagnostics, null, null, compilationUnits)
                .call();

        for (Diagnostic<? extends JavaFileObject> diagnostic : diagnostics
                .getDiagnostics()) {
            String diagnosticMessage = String.format("Error on line %d in %s%n",
                    diagnostic.getLineNumber(), diagnostic.getSource().toUri() + " : \n\t" + diagnostic.getMessage(null));

            /*Following gives out of box good message, but I used above to show the custom use of diagnostic
             * String diagnosticMessage = diagnostic.toString();*/

            errorList.add(diagnosticMessage);
        }
        try {
            fileManager.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return errorList;
    }
}

Taken from Best way to process/handle Error stream messages

Community
  • 1
  • 1
11thdimension
  • 10,333
  • 4
  • 33
  • 71
0

If you just want to check if it is a valid Java class (that can be compiled), you can try.

 try {
            Class<?> clazz = MyTest.class.getClassLoader().loadClass("TargetClass");
            clazz.newInstance();
            } catch (Throwable e) { // Not a good idea to catch error, for test purpose only.
                if(e instanceof Error && e.getMessage().contains("Unresolved compilation problems")){
                    Assert.fail("Invalid class");
                }
            }

You might have to call "javac" process (see how to compile & run java program in another java program?) to make sure TargetClass.class is available before running this test check.

Community
  • 1
  • 1
MIK
  • 392
  • 3
  • 19