2

Can we use JUnit to test java batch jobs? Since Junit runs locally and java batch jobs run on the server, i am not sure how to start a job (i tried using using the JobOperator class) from JUnit test cases.

If JUnit is not the right tool, how can we unit test java batch code.

I am using using IBM's implementation of JSR 352 running on WAS Liberty

ᄂ ᄀ
  • 5,669
  • 6
  • 43
  • 57
Fazil Hussain
  • 425
  • 3
  • 16

2 Answers2

2

JUnit is first of all an automation and test monitor framework. Meaning: you can use it to drive all kinds of @Test methods.

From an conceptual point, the definition of unit tests is pretty vague; if you follow wikipedia, "everything you do to test something" can be seen as unit test. Following that perspective, of course, you can "unit test" batch code that runs on a batch framework.

But: most people think that "true", "helpful" unit tests do not require the presence of any external thing. Such tests can be run "locally" at build time. No need for servers, file systems, networking, ...

Keeping that in mind, I think there are two things you can work with:

  1. You can use JUnit to drive "integration" or "functional tests". Meaning: you can define test suites that do the "full thing" - define batches, have them processed to check for expected results in the end. As said, that would be integration tests that make sure the end-to-end flow works as expected.
  2. You look into"normal" JUnit unit-testing. Meaning: you focus on those aspects in your code that are "un-related" to the batch framework (in other words: look out for POJOs) and unit-test those. Locally; maybe with mocking frameworks; without relying on a real batch service running your code.
Community
  • 1
  • 1
GhostCat
  • 137,827
  • 25
  • 176
  • 248
2

Building on the answer from @GhostCat, it seems you're asking how to drive the full job (his bullet 1.) in your tests. (Of course unit testing the reader/processor/writer components individually can also be useful.)

Your basic options are:

  1. Use Arquillian (see here for a link on getting started with Arquillian and Liberty) to run your tests in the server but to let Arquillian handle the tasks of deploying the app to the server and collecting the results.

  2. Write your own servlet harness driving your job through the JobOperator interface. See the answer by @aguibert to this question for a starting point. Note you'll probably want to write your own simple routine polling the JobExecution for one of the "finished" states (COMPLETED, FAILED, or STOPPED) unless your jobs have some other means of making the submitter aware.


Another technique to keep in mind is the startup bean. You can run your jobs simply by starting the server with a startup bean like:

@Startup
@Singleton
public class StartupBean {

    JobOperator jobOp = BatchRuntime.getJobOperator();

    // Drive job(s) on startup.
    jobOp.start(...);        

This can be useful if you have a way to check the job results separate from using the JobOperator interface (for which you need to be in the server). Your tests can simply poll and check for the job results. You don't even have to open an HTTP port, and the server startup overhead is only a few seconds.

Community
  • 1
  • 1
Scott Kurz
  • 4,985
  • 1
  • 18
  • 40