I am writing a custom ant task that extends Task. I am using the log() method in the task. What I want to do is use a unit test while deveoping the task, but I don't know how to set up a context for the task to run in to initialise the task as if it were running in ant.
This is the custom Task:
public class CopyAndSetPropertiesForFiles extends Task {
public void execute() throws BuildException {
log("CopyAndSetPropertiesForFiles begin execute()");
log("CopyAndSetPropertiesForFiles end execute()");
}
}
This is the unit test code:
CopyAndSetPropertiesForFiles task = new CopyAndSetPropertiesForFiles();
task.execute();
When the code is run as a test it gives a NullPointerException when it calls log.
java.lang.NullPointerException
at org.apache.tools.ant.Task.log(Task.java:346)
at org.apache.tools.ant.Task.log(Task.java:334)
at uk.co.tbp.ant.custom.CopyAndSetPropertiesForFiles.execute(CopyAndSetPropertiesForFiles.java:40)
at uk.co.tbp.ant.custom.test.TestCopyAndSetPropertiesForFiles.testCopyAndSetPropertiesForFiles(TestCopyAndSetPropertiesForFiles.java:22)
Does anybody know a way to provide a context or stubs or something similar to the task?
Thanks,
Rob.
Accepted answer from Abarax. I was able to call task.setProject(new Project()); The code now executes OK (except no logging appears in th console - at least I can exercise the code :-) ).
The use of Ant makes it straight forward through the JUnit task.
**\*.sql means "in the given directory and inside all of its subdirectories, all the files that end with .sql"
Or better yet, decouple the task object itself from the logic (lets call it TaskImpl) inside the task - so that you can pass in your own dependencies (e.g., the logger). Then, instead of testing the task object, you test TaskImpl -> which you can pass in the logger, and any other weird bits and pieces it might need to do its job. Then unit testing is a matter of mocking the dependencies.
Looking at the Ant source code these are the two relevent classes: ProjectComponent and Task
You are calling the log method from Task:
public void log(String msg) {
log(msg, Project.MSG_INFO);
}
Which calls:
public void log(String msg, int msgLevel) {
if (getProject() != null) {
getProject().log(this, msg, msgLevel);
} else {
super.log(msg, msgLevel);
}
}
Since you do not have project set it will call "super.log(msg, msgLevel)"
public void log(String msg, int msgLevel) {
if (getProject() != null) {
getProject().log(msg, msgLevel);
} else {
// 'reasonable' default, if the component is used without
// a Project ( for example as a standalone Bean ).
// Most ant components can be used this way.
if (msgLevel <= Project.MSG_INFO) {
System.err.println(msg);
}
}
}
It looks like this may be your problem. Your task needs a project context.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With