Announcement Announcement Module
No announcement yet.
Problems unit testing batch jobs with Unitils and Dbunit Page Title Module
Move Remove Collapse
Conversation Detail Module
  • Filter
  • Time
  • Show
Clear All
new posts

  • Problems unit testing batch jobs with Unitils and Dbunit

    We are running batch 1.1.4-RELEASE.
    We are unit testing our batch ItemWriter/tasklets classes quiet extensively using Unitils (2.2) with the testng implementation and DbUnit.

    I am not able to test the "Jobs", - loading the job, - xml, - launched with the JobLauncher and the SyncTaskExecutor().

    My problem is that DataSet loaded by DbUnit is not visible to the HibernateCursorItemReader configured in the job.xml. I believe it has something to do with the Transaction scope the job is loaded into. Testing tasklets using DbUnit works fine.

    Any tip would be appreciated.


  • #2
    Can you slow it down a bit and explain what you expect to see, and what you are not seeing in the database, and what steps are being taken to get it there?


    • #3
      What I expect to see is the DataSet - annotated and loaded into the database being visible to the HibernateCursorItemReader. By this I am able to perform an Assert test before and after the batchJob has been executed.

      In the enclosed code example is the data loaded by DbUnit visible to by managers before and after the job has been executed, - but not to the HibernateCursorItemReader. If I disable all Transactions, - the data is visible to the reader. It seems to me that the Job is not taking part in the transaction established by DbUnit/Unitils.


          @Test(enabled = true)
          public void testInvoiceMassCreditJob() throws Exception  {
              List<InvoiceBean> preJobExecution = invoicingManager.fetchInvoicesByPaymentAgreementId( 1);
              runJob(BatchJob.INVOICE_MASSCREDIT_JOB, ",,max.retries=8,"+"unik="+System.currentTimeMillis());
              List<InvoiceBean> invoices = invoicingManager.fetchInvoicesByPaymentAgreementId( 1);
              Assert.assertEquals( invoices.size(), 2);
              for ( InvoiceBean invoice: invoices) {
                  if (InvoiceType.CREDIT_NOTE.equals( invoice.getInvoiceType())) {
                      Assert.assertEquals( invoice.getParentCrmInvoiceId(), "1-12345");
                      Assert.assertEquals( invoice.getAmount(), -125.50d);
                  } else if ( InvoiceType.INVOICE.equals( invoice.getInvoiceType())) {
                      Assert.assertEquals( invoice.getAmount(), 125.50d);
                  } else {
             "There should not be any invoices with type <> CREDIT_NOTE/INVOICE");


      • #4
        If DbUnit is creating a transaction then Spring certainly doesn't know about it. It might be possible to teach DbUnit to use a Spring transaction manager (I never tried), but I'm not sure it's worth the effort. It is not in general possible to run a job inside a transaction, since it will want to read and write data and most of the time you will be using a Step implementation that needs a Spring transaction manager. If that's an important feature, we could maybe look at how to provide it in the framework at some point. Open a JIRA.