<!DOCTYPE html>
<html lang="en">
  <head>

    <meta charset="UTF-8">
      <title>Unit Testing Transactions</title>
    <meta name="description" content="Apache TomEE">
    <meta name="author" content="Apache TomEE">
    <meta name="google-translate-customization" content="f36a520c08f4c9-0a04e86a9c075ce9-g265f3196f697cf8f-10">
    <meta http-equiv="Pragma" content="no-cache">
    <meta http-equiv="Expires" content="0">
    <meta http-equiv="Cache-Control" content="no-store, no-cache, must-revalidate, max-age=0">

    <!-- Le HTML5 shim, for IE6-8 support of HTML elements -->
    <!--[if lt IE 9]>
      <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
    <![endif]-->

    <!-- Le styles -->
    <link href="./resources/css/bootstrap.css" rel="stylesheet">
    <link href="./resources/css/prettify.css" rel="stylesheet">
    <!--link href="./resources/css/bootstrap-mods.css" rel="stylesheet"-->
    <link href="./resources/css/main.css" rel="stylesheet">
    <link href="./resources/font-awesome-4.6.3/css/font-awesome.min.css" rel="stylesheet">

    <script type="text/javascript">
        var t = encodeURIComponent(document.title.replace(/^\s+|\s+$/g,""));
        var u = encodeURIComponent(""+document.URL);
    
      function fbshare () {
          window.open(
                  "http://www.facebook.com/sharer/sharer.php?u="+u,
                  'Share on Facebook',
                  'width=640,height=426');
      };
      function gpshare () {
          window.open(
                  "https://plus.google.com/share?url="+u,
                  'Share on Google+',
                  'width=584,height=385');
      };
      function twshare () {
          window.open(
                  "https://twitter.com/intent/tweet?url="+u+"&text="+t,
                  'Share on Twitter',
                  'width=800,height=526');
      };
      function pinshare () {
          window.open("//www.pinterest.com/pin/create/button/?url="+u+"&media=http%3A%2F%2Ftomee.apache.org%2Fresources%2Fimages%2Ffeather-logo.png&description="+t,
                  'Share on Pinterest',
                  'width=800,height=526');
      };
    </script>

    <!-- Le fav and touch icons -->
    <link rel="shortcut icon" href="./favicon.ico">
    <link rel="apple-touch-icon" href="./resources/images/apple-touch-icon.png">
    <link rel="apple-touch-icon" sizes="72x72" href="./resources/images/apple-touch-icon-72x72.png">
    <link rel="apple-touch-icon" sizes="114x114" href="./resources/images/apple-touch-icon-114x114.png">

    <script src="./resources/js/prettify.js" type="text/javascript"></script>
    <script src="./resources/js/jquery-latest.js"></script>
    <script src="http://platform.twitter.com/widgets.js" type="text/javascript"></script>
    <script src="./resources/js/common.js"></script>
    <script src="./resources/js/prettyprint.js"></script>
    <!--script src="//assets.pinterest.com/js/pinit.js" type="text/javascript" async></script//-->
    
    <script type="text/javascript">

      var _gaq = _gaq || [];
      _gaq.push(['_setAccount', 'UA-2717626-1']);
      _gaq.push(['_setDomainName', 'apache.org']);
      _gaq.push(['_trackPageview']);

      (function() {
        var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
        ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
        var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
      })();

    </script>
  </head>

  <body>

    <div class="topbar" data-dropdown="dropdown">
      <div class="fill">
        <div class="container">
          <a class="brand" href="./index.html">Apache TomEE</a>
          <ul class="nav">
              <li class="dropdown">
                  <a class="dropdown-toggle" data-toggle="dropdown" href="#">
                  Apache
                      <b class="caret"></b>
                  </a>
                  <ul class="dropdown-menu">
                     <!-- <li><a href="./misc/whoweare.html">Who we are?</a></li> -->
                     <!-- <li><a href="./misc/heritage.html">Heritage</a></li> -->
                     <li><a href="http://www.apache.org">Apache Home</a></li>
                     <!-- <li><a href="./misc/resources.html">Resources</a></li> -->
                     <li><a href="./misc/contact.html">Contact</a></li>
                     <li><a href="./misc/legal.html">Legal</a></li>
                     <li><a href="http://www.apache.org/foundation/sponsorship.html">Sponsorship</a></li>
                     <li><a href="http://www.apache.org/foundation/thanks.html">Thanks</a></li>
                     <li class="divider"/>
                     <li><a href="http://www.apache.org/security">Security</a></li>
                  </ul>
              </li>
              <li><a href="./index.html">Home</a></li>
              <li><a href="./downloads.html">Downloads</a></li>
              <li><a href="./documentation.html">Documentation</a></li>
              <li><a href="./examples-trunk/index.html">Examples</a></li>
              <li><a href="./support.html">Support</a></li>
              <li><a href="./contribute.html">Contribute</a></li>
              <li><a href="./security/index.html">Security</a></li>
          </ul>

            <!-- Google CSE Search Box Begins  -->
            <FORM class="pull-right" id="searchbox_010475492895890475512:_t4iqjrgx90" action="http://www.google.com/cse">
                <INPUT type="hidden" name="cx" value="010475492895890475512:_t4iqjrgx90">
                <INPUT type="hidden" name="cof" value="FORID:0">
                <INPUT size="18" width="130" style="width:130px" name="q" type="text" placeholder="Search">
            </FORM>
            <!--<SCRIPT type="text/javascript" src="http://www.google.com/coop/cse/brand?form=searchbox_010475492895890475512:_t4iqjrgx90"></SCRIPT>-->
            <!-- Google CSE Search Box Ends -->
        </div>
      </div>
    </div>

    <div class="container">
    

<div class="page-header">
    <small><a href="./index.html">Home</a></small><br>
    <h1>Unit Testing Transactions

        <div style="float: right; position: relative; bottom: -10px; ">
            <a onclick="javascript:gpshare()" class="gp-share sprite" title="Share on Google+">share [gp]</a>
            <a onclick="javascript:fbshare()" class="fb-share sprite" title="Share on Facebook">share [fb]</a>
            <a onclick="javascript:twshare()" class="tw-share sprite" title="Share on Twitter">share [tw]</a>
            <a onclick="javascript:pinshare()" class="pin-share sprite" title="Share on Pinterest">share [pin]</a>
            <a data-toggle="modal" href="#edit" class="edit-page" title="Contribute to this Page">contribute</a>
        </div>
    </h1>
</div>

<p><a name="UnitTestingTransactions-Basicsetup"></a></p>

<h1>Basic setup</h1>

<p>Add the following interface and bean to your test sources (they could even
be inner classes of a test case):</p>

<p><a name="UnitTestingTransactions-Businessinterface"></a></p>

<h2>Business interface</h2>

<pre><code>public interface Caller {
    public &lt;V&gt; V call(Callable&lt;V&gt; callable) throws Exception;
}
</code></pre>

<p><a name="UnitTestingTransactions-BeanImplementation(s)"></a></p>

<h2>Bean Implementation(s)</h2>

<pre><code>import java.util.concurrent.Callable;

@Stateless
@TransactionAttribute(REQUIRES_NEW)
public class TransactionBean implements Caller {
    public &lt;V&gt; V call(Callable&lt;V&gt; callable) throws Exception {
    return callable.call();
    }
}
</code></pre>

<p><a name="UnitTestingTransactions-Havethemdiscovered"></a></p>

<h2>Have them discovered</h2>

<p>In src/test/resources/ (or related) create an META-INF/ejb-jar.xml
containing the text "<ejb-jar/>"</p>

<p><a name="UnitTestingTransactions-Whatweaccomplished"></a></p>

<h2>What we accomplished</h2>

<p>Essentially what we've done is added an ejb that will be picked up as part
of your test code and deployed.  You can then look it up and use it to
execute test code with any particular transaction or security constraints
that you want.  The above bean specifies REQUIRES_NEW; functionally the
same as REQUIRED as the test case itself won't have a transaction, but a
little cleaner and more explicit.  </p>

<p>You could also annotate the bean with @RunAs("manager") for example and
test that your security restrictions are how you like them.  You can have
as many of these test beans in your test code as you like, each with it's
own transaction and security constraints allowing you to write some
incredibly thorough tests.</p>

<p>You do not need to use java.util.concurrent.Callable, any similar interface
of your creation could work just as well.  You may want something with
return type void, for example, to eliminate useless 'return null'
statements.</p>

<p><a name="UnitTestingTransactions-Usage"></a></p>

<h1>Usage</h1>

<p>There are a number of style choices for using the above bean, specifically
around the creation of the Callable object you pass in, and it all really
depends on what looks nice to you.</p>

<p>In the examples below, the Movies bean being tested is simply a thin layer
around JPA that allows us to use enforce various transaction semantics.</p>

<pre><code>import javax.ejb.Stateful;
import javax.ejb.TransactionAttribute;
import static javax.ejb.TransactionAttributeType.MANDATORY;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.PersistenceContextType;
import javax.persistence.Query;
import java.util.List;

@Stateful(name = "Movies")
@TransactionAttribute(MANDATORY)
public class MoviesImpl implements Movies {

    @PersistenceContext(unitName = "movie-unit", type = PersistenceContextType.TRANSACTION)
    private EntityManager entityManager;

    public void addMovie(Movie movie) throws Exception {
    entityManager.persist(movie);
    }

    public void deleteMovie(Movie movie) throws Exception {
    entityManager.remove(movie);
    }

    public List&lt;Movie&gt; getMovies() throws Exception {
    Query query = entityManager.createQuery("SELECT m from Movie asm");
    return query.getResultList();
    }
}
</code></pre>

<p>Test code below.</p>

<p><a name="UnitTestingTransactions-Pureinlined"></a></p>

<h2>Pure inlined</h2>

<p>The Callable can be created right in the test method itself.</p>

<pre><code>public class MoviesTest extends TestCase {
    private Context context;

    protected void setUp() throws Exception {
    // initialize jndi context as usual
    }

    public void test() throws Exception {
    Caller transactionBean = (Caller)
    context.lookup("TransactionBeanLocal");

    transactionBean.call(new Callable() {
        public Object call() throws Exception {
        Movies movies = (Movies) context.lookup("MoviesLocal");

        movies.addMovie(new Movie("Quentin Tarantino", "Reservoir Dogs", 1992));
        movies.addMovie(new Movie("Joel Coen", "Fargo", 1996));
        movies.addMovie(new Movie("Joel Coen", "The Big Lebowski",1998));

        List&lt;Movie&gt; list = movies.getMovies();
        assertEquals("List.size()", 3, list.size());

        for (Movie movie : list) {
            movies.deleteMovie(movie);
        }

        assertEquals("Movies.getMovies()", 0,movies.getMovies().size());

        return null;
        }
    });
    }
}
</code></pre>

<p><a name="UnitTestingTransactions-Sametestcode,differenttransactionscenarios"></a></p>

<h2>Same test code, different transaction scenarios</h2>

<p>Maybe you'd like to test how things behave with and without a transaction
to guarantee everyone is doing the right thing in all situations.  Negative
testing is often a very good way to stomp out dangerous bugs.</p>

<pre><code>public class MoviesTest extends TestCase {
    private Context context;

    protected void setUp() throws Exception {
    // initialize jndi context as usual
    }

    private void doWork() throws Exception {
          Movies movies = (Movies) context.lookup("MoviesLocal");

          movies.addMovie(new Movie("Quentin Tarantino", "Reservoir Dogs",1992));
          movies.addMovie(new Movie("Joel Coen", "Fargo", 1996));
          movies.addMovie(new Movie("Joel Coen", "The Big Lebowski", 1998));

          List&lt;Movie&gt; list = movies.getMovies();
          assertEquals("List.size()", 3, list.size());

          for (Movie movie : list) {
              movies.deleteMovie(movie);
          }

          assertEquals("Movies.getMovies()", 0, movies.getMovies().size());
    }

    public void testWithTransaction() throws Exception {
          Caller transactionBean = (Caller)context.lookup("TransactionBeanLocal");

          transactionBean.call(new Callable(){
                public Object call() throws Exception {
                  doWork();
                  return null;
                }
          });
    }

    public void testWithoutTransaction() throws Exception {
          try {
                doWork();
                fail("The Movies bean should be using TransactionAttributeType.MANDATORY");
          } catch (javax.transaction.TransactionRequiredException e) {
                // good, our Movies bean is using TransactionAttributeType.MANDATORY as we want
          }
    }
}
</code></pre>




        <div id="edit" class="modal hide fade in" style="display: none; ">
            <div class="modal-header">
                <a class="close" data-dismiss="modal">x</a>

                <h3>Thank you for contributing to the documentation!</h3>
            </div>
            <div class="modal-body">
                <h4>Any help with the documentation is greatly appreciated.</h4>
                <p>All edits are reviewed before going live, so feel free to do much more than fix typos or links.  If you see a page that could benefit from an entire rewrite, we'd be thrilled to review it.  Don't be surprised if we like it so much we ask you for help with other pages :)</p>
                <small>NOTICE: unless indicated otherwise on the pages in question, all editable content available from apache.org is presumed to be licensed under the Apache License (AL) version 2.0 and hence all submissions to apache.org treated as formal Contributions under the license terms.</small>
                <!--[if gt IE 6]>
                <h4>Internet Explorer Users</h4>
                <p>If you are not an Apache committer, click the Yes link and enter a <i>anonymous</i> for the username and leave the password empty</p>
                <![endif]-->

            </div>
            <div class="modal-footer">
                Do you have an Apache ID?
                <a href="javascript:void(location.href='https://cms.apache.org/redirect?uri='+escape(location.href))" class="btn">Yes</a>
                <a href="javascript:void(location.href='https://anonymous:@cms.apache.org/redirect?uri='+escape(location.href))" class="btn">No</a>
            </div>
        </div>
        <script src="./resources/js/bootstrap-modal.js"></script>

        <footer>
            <p>Copyright &copy; 1999-2016 The Apache Software Foundation, Licensed under the Apache License, Version 2.0.
                Apache TomEE, TomEE, Apache, the Apache feather logo, and the Apache TomEE project logo are trademarks of The Apache Software Foundation.
                All other marks mentioned may be trademarks or registered trademarks of their respective owners.</p>
        </footer>

    </div> <!-- /container -->

    <!-- Javascript
    ================================================== -->
    <!-- Placed at the end of the document so the pages load faster -->
    <script src="./resources/js/bootstrap-dropdown.js"></script>

  </body>
</html>
