2 Replies Latest reply on Oct 13, 2014 8:53 AM by bmajsak

    Rollback transaction for Arquillian testing - getting NullPointerException

    altosaxwannabe

      Description

      I'm having a problem with creating an Arquillian test that rollbacks database operations at the end of execution. It throws a NullPointerException when trying to rollback the transaction because it can't find the org.jboss.arquillian.test.spi.TestResult instance from theorg.jboss.arquillian.test.impl.context.TestContextImpl instance (testResultInstance.get() returns null, below).

      I'm using arquillian-1.1.2-Final and arquillian-transaction-api-1.0.0-FINAL and testng-6.8.

      I can see the transaction being created correctly at the beginning of the test method but I can't figure out why the org.jboss.arquillian.test.spi.TestResult is not set correctly and throws the exception.

      Note: If I remove the @Transactional annotation from the test class, everything works fine. Also, in this test you'll see that there are no updates/inserts to the database but that's just for the sake of simplicity. If I add an update statement to it, the record is updated correctly but the change is persisted after the test ends (if I remove the @Transactional annotation from the test class) and I want to prevent that by rolling it back...

       

      Info

      Code where exception happens (first line of method below - fromorg.jboss.arquillian.transaction.impl.lifecycle.TransactionHandler):

      /**
      * Returns whether the test requires to be rolled back. </p>
      * By default it will return true if the last executed test has failed.
      *
      * @return true if test requires rollback, false otherwise
      */

      private boolean testRequiresRollbackDueToFailure()
      {
        
      final Status actualStatus = testResultInstance.get().getStatus();
        
      return TestResult.Status.FAILED.equals(actualStatus);
      }


      Exception stacktrace:

      java.lang.NullPointerException
        at org
      .jboss.arquillian.transaction.impl.lifecycle.TransactionHandler.testRequiresRollbackDueToFailure(TransactionHandler.java:159)
        at org
      .jboss.arquillian.transaction.impl.lifecycle.TransactionHandler.rollbackRequired(TransactionHandler.java:148)
        at org
      .jboss.arquillian.transaction.impl.lifecycle.TransactionHandler.endTransactionAfterTest(TransactionHandler.java:109)
        at sun
      .reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun
      .reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun
      .reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java
      .lang.reflect.Method.invoke(Method.java:597)
        at org
      .jboss.arquillian.core.impl.ObserverImpl.invoke(ObserverImpl.java:94)
        at org
      .jboss.arquillian.core.impl.EventContextImpl.invokeObservers(EventContextImpl.java:99)
        at org
      .jboss.arquillian.core.impl.EventContextImpl.proceed(EventContextImpl.java:81)
        at org
      .jboss.arquillian.testenricher.cdi.CreationalContextDestroyer.destory(CreationalContextDestroyer.java:44)
        at sun
      .reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun
      .reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun
      .reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java
      .lang.reflect.Method.invoke(Method.java:597)
        at org
      .jboss.arquillian.core.impl.ObserverImpl.invoke(ObserverImpl.java:94)
        at org
      .jboss.arquillian.core.impl.EventContextImpl.proceed(EventContextImpl.java:88)
        at org
      .jboss.arquillian.test.impl.TestContextHandler.createTestContext(TestContextHandler.java:102)
        at sun
      .reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun
      .reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun
      .reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java
      .lang.reflect.Method.invoke(Method.java:597)
        at org
      .jboss.arquillian.core.impl.ObserverImpl.invoke(ObserverImpl.java:94)
        at org
      .jboss.arquillian.core.impl.EventContextImpl.proceed(EventContextImpl.java:88)
        at org
      .jboss.arquillian.test.impl.TestContextHandler.createClassContext(TestContextHandler.java:84)
        at sun
      .reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun
      .reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun
      .reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java
      .lang.reflect.Method.invoke(Method.java:597)
        at org
      .jboss.arquillian.core.impl.ObserverImpl.invoke(ObserverImpl.java:94)
        at org
      .jboss.arquillian.core.impl.EventContextImpl.proceed(EventContextImpl.java:88)
        at org
      .jboss.arquillian.test.impl.TestContextHandler.createSuiteContext(TestContextHandler.java:65)
        at sun
      .reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun
      .reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun
      .reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java
      .lang.reflect.Method.invoke(Method.java:597)
        at org
      .jboss.arquillian.core.impl.ObserverImpl.invoke(ObserverImpl.java:94)
        at org
      .jboss.arquillian.core.impl.EventContextImpl.proceed(EventContextImpl.java:88)
        at org
      .jboss.arquillian.core.impl.ManagerImpl.fire(ManagerImpl.java:135)
        at org
      .jboss.arquillian.core.impl.ManagerImpl.fire(ManagerImpl.java:115)
        at org
      .jboss.arquillian.test.impl.EventTestRunnerAdaptor.after(EventTestRunnerAdaptor.java:103)
        at org
      .jboss.arquillian.testng.Arquillian.arquillianAfterTest(Arquillian.java:149)
        at sun
      .reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun
      .reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun
      .reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java
      .lang.reflect.Method.invoke(Method.java:597)
        at org
      .testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:84)
        at org
      .testng.internal.Invoker.invokeConfigurationMethod(Invoker.java:564)
        at org
      .testng.internal.Invoker.invokeConfigurations(Invoker.java:213)
        at org
      .testng.internal.Invoker.invokeMethod(Invoker.java:786)
        at org
      .testng.internal.Invoker.invokeTestMethod(Invoker.java:901)
        at org
      .testng.internal.Invoker.invokeTestMethods(Invoker.java:1231)
        at org
      .testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:127)
        at org
      .testng.internal.TestMethodWorker.run(TestMethodWorker.java:111)
        at org
      .testng.TestRunner.privateRun(TestRunner.java:767)
        at org
      .testng.TestRunner.run(TestRunner.java:617)
        at org
      .testng.SuiteRunner.runTest(SuiteRunner.java:334)
        at org
      .testng.SuiteRunner.runSequentially(SuiteRunner.java:329)
        at org
      .testng.SuiteRunner.privateRun(SuiteRunner.java:291)
        at org
      .testng.SuiteRunner.run(SuiteRunner.java:240)
        at org
      .testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
        at org
      .testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86)
        at org
      .testng.TestNG.runSuitesSequentially(TestNG.java:1224)
        at org
      .testng.TestNG.runSuitesLocally(TestNG.java:1149)
        at org
      .testng.TestNG.run(TestNG.java:1057)
        at org
      .jboss.arquillian.testng.container.TestNGTestRunner.execute(TestNGTestRunner.java:53)
        at org
      .jboss.arquillian.protocol.servlet.runner.ServletTestRunner.executeTest(ServletTestRunner.java:160)
        at org
      .jboss.arquillian.protocol.servlet.runner.ServletTestRunner.execute(ServletTestRunner.java:126)
        at org
      .jboss.arquillian.protocol.servlet.runner.ServletTestRunner.doGet(ServletTestRunner.java:90)
        at javax
      .servlet.http.HttpServlet.service(HttpServlet.java:734)
        at javax
      .servlet.http.HttpServlet.service(HttpServlet.java:847)
        at org
      .apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:329)
        at org
      .apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248)
        at org
      .jboss.weld.servlet.ConversationPropagationFilter.doFilter(ConversationPropagationFilter.java:62)
        at org
      .apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:280)
        at org
      .apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248)
        at org
      .apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:275)
        at org
      .apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:161)
        at org
      .jboss.as.jpa.interceptor.WebNonTxEmCloserValve.invoke(WebNonTxEmCloserValve.java:50)
        at org
      .jboss.as.web.security.SecurityContextAssociationValve.invoke(SecurityContextAssociationValve.java:153)
        at org
      .apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:155)
        at org
      .apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
        at org
      .apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
        at org
      .apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:368)
        at org
      .apache.coyote.http11.Http11Processor.process(Http11Processor.java:877)
        at org
      .apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:671)
        at org
      .apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:930)
        at java
      .lang.Thread.run(Thread.java:619)


      Test class:

      package ie.one23.insurance.common.dao.config;

      import ie.one23.insurance.motor.dao.lookup.LookupDao;
      import ie.one23.insurance.motor.util.PackagingUtil;

      import javax.inject.Inject;

      import org.apache.poi.hssf.record.formula.functions.Lookup;
      import org.jboss.arquillian.container.test.api.Deployment;
      import org.jboss.arquillian.container.test.api.OverProtocol;
      import org.jboss.arquillian.testng.Arquillian;
      import org.jboss.arquillian.transaction.api.annotation.TransactionMode;
      import org.jboss.arquillian.transaction.api.annotation.Transactional;
      import org.jboss.shrinkwrap.api.spec.WebArchive;
      import org.junit.Assert;
      import org.testng.annotations.Test;

      @Transactional(TransactionMode.ROLLBACK)
      public class TermsOfBusinessUrlDaoTest extends Arquillian {

        
      @Deployment
        
      @OverProtocol("Servlet 3.0")
        
      public static WebArchive createDeployment() {
        
      WebArchive war = PackagingUtil.getWebArchiveForEJB();
        
      return war;
        
      }

        
      @Inject
        
      LookupDao lookupDao;

        
      @Test(groups = { "daos", "integration", "arquillian" })
        
      public void testFindValidLinkByCode() {
        
      Lookup lookup = lookupDao.findValidLinkByCode("example");

        
      Assert.assertNotNull(lookup);
        
      Assert.assertEquals("example", lookup.getCode());
        
      Assert.assertEquals(true, lookup.getActive());
        
      }
      }


      arquillian.xml

      <arquillian xmlns="http://jboss.org/schema/arquillian" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        
      xsi:schemaLocation="
        http://jboss.org/schema/arquillian
        http://jboss.org/schema/arquillian/arquillian_1_0.xsd"
      >

        
      <container qualifier="jboss-remote" default="false">
        
      <configuration>
        
      <property name="managementAddress">${mgmtAddr:127.0.0.1}</property>
        
      <property name="managementPort">${mgmtPort:9999}</property>
        
      </configuration>
        
      </container>

        
      <extension qualifier="transaction">
        
      <property name="manager">java:jboss/TransactionManager</property>
        
      </extension>

        
      <extension qualifier="persistence">
        
      <property name="defaultTransactionMode">ROLLBACK</property>
        
      </extension>
      </arquillian>


      The unit tests that are part of arquillian-extension-transaction show a bind of the TestResult before invoking the test method (@see shouldRollbackTransaction() test):

      If I remove the bind instruction, I get the same exception... Is this a bug?

      See the following URL: https://github.com/arquillian/arquillian-extension-transaction/blob/master/impl-base/src/test/java/org/jboss/arquillian/transaction/impl/lifecycle/ClientSideTransactionHandlerTestCase.java

      @Test
      public void shouldRollbackTransaction() throws Exception
      {

        getManager
      ().getContext(ClassContext.class).activate(TestClass.class);

       
      Object instance = new TestClass();
       
      Method testMethod = instance.getClass().getMethod("rollbackTest");

        bind
      (TestScoped.class, TestResult.class, new TestResult(TestResult.Status.PASSED));

        getManager
      ().fire(new org.jboss.arquillian.test.spi.event.suite.After(instance, testMethod));

       
      // checks if the transaction context has been disposed
        verify
      (mockTransactionContext).destroy();

       
      // verifies that the transaction has been rollback
        verify
      (mockTransactionProvider).rollbackTransaction(any(TransactionalTest.class));

        getManager
      ().getContext(ClassContext.class).deactivate();

       

      Thank you,

      Eduardo