tomee-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Alexander Saint Croix" <saintx.opensou...@gmail.com>
Subject Re: Transactions controlled by Unit Tests
Date Tue, 12 Feb 2008 15:19:16 GMT
Jack,

Funny you should ask--I was working on the same thing last week.
http://weblogs.java.net/blog/saintx/archive/2008/02/lambda_function.htmlshows
a good start on how to do this.

The transactions are controlled by a stateless session bean in the base
class, and the method blocks of the test case are broken down into units of
work, then fed into this session bean as Callable objects.  Each callable is
wrapped in its own transaction.  The "getCalls" method is abstract in the
base and gets called by the "test..." method in the base class, so extending
the base requires implementing "getCalls".

Now, the way I do my CRUD tests is slightly different.  They look like this:

public class CRUDTest extends CascadeTestBase {
>
>     public Callable[] getCalls() {
>         return toCallableArray(
>         getCRUD(new Address(), "Address"),
>         getCRUD(new AssociatedAddress(), "AssociatedAddress"),
>         getCRUD(new EmailAddress(), "EmailAddress"),
>         getCRUD(new GeographicAddress(), "GeographicAddress"),
>         getCRUD(new ISOCountryCode(), "ISOCountryCode"),
>         getCRUD(new Locale(), "Locale"),
>         getCRUD(new TelecomAddress(), "TelecomAddress"),
>         getCRUD(new WebPageAddress(), "WebPageAddress"),
>         getCRUD(new AssignedResponsibility(), "AssignedResponsibility"),
>         getCRUD(new Capability(), "Capability"),
>         getCRUD(new PartyRelationship(), "PartyRelationship"),
>         getCRUD(new PartyRelationshipType(), "PartyRelationshipType"),
>         getCRUD(new PartyRole(), "PartyRole"),
>         getCRUD(new PartyRoleType(), "PartyRoleType"),
>         getCRUD(new Responsibility(), "Responsibility"),
>         getCRUD(new Organization(), "Organization"),
>         getCRUD(new OrganizationName(), "OrganizationName"),
>         getCRUD(new Party(), "Party"),
>         getCRUD(new PartySignature(), "PartySignature"),
>         getCRUD(new Person(), "Person"),
>         getCRUD(new PersonName(), "PersonName"),
>         getCRUD(new Binding(), "Binding"),
>         getCRUD(new BindingValue(), "BindingValue"),
>         getCRUD(new BindingType(), "BindingType"));
>     }
>
>     private <T extends Archetype> Callable[] getCRUD(T stem, String
> table){
>         return new Tester<T>(stem, table).getCalls();
>     }
>
>     private Callable[] toCallableArray(Callable[]... array) {
>         final int l = array.length;
>         final int l2 = 3;
>         Callable[] result = new Callable[l * l2];
>
>         for (int i = 0; i < l; i++) {
>             Callable[] subarray = array[i];
>             for (int j = 0; j < l2; j++) {
>                 result[i * l2 + j] = subarray[j];
>             }
>         }
>         return result;
>     }
>
>     private class Tester<T extends Archetype> {
>         private Retriever<T> bean;
>         private T o1, o2;
>         private String table;
>         private long ID;
>
>         public Tester(T o1, String table) {
>             this.table = table;
>             this.o1 = o1;
>         }
>
>         public Callable phase01() {
>             return new Callable() {
>                 public Object call() {
>
>                     // CREATE
>                     assertEquals(0, o1.getID());
>                     mgr.persist(o1);
>                     mgr.flush();
>                     ID = o1.getID();
>                     return null;
>                 }
>             };
>         }
>
>         public Callable phase02() {
>             return new Callable() {
>                 public Object call() {
>
>                     // READ & UPDATE
>                     assertEquals(
>                             "Failed size check for table named \""
>                                     + table + "\"",
>                             1,
>                             mgr.sizeOf(table));
>
>                     bean = new Retriever<T>(table, ID);
>                     o2 = bean.fetch();
>                     Assert.assertNotNull(o2);
>                     o2.setName("name of bean");
>                     o2 = null;
>                     return null;
>                 }
>             };
>         }
>
>         public Callable phase03() {
>             return new Callable() {
>                 public Object call() {
>
>                     // VERIFY UPDATE
>                     assertEquals(1, mgr.sizeOf(table));
>                     bean = new Retriever<T>(table, ID);
>                     o2 = bean.fetch();
>                     assertNotNull(o2);
>                     assertEquals("name of bean", o2.getName());
>
>                     // DESTROY
>                     mgr.remove(o2);
>                     mgr.flush();
>                     assertEquals(0, mgr.sizeOf(table));
>                     return null;
>                 }
>             };
>         }
>
>         /**
>          * Retrieve units of work for this CRUD test block
>          * @return Callable[] units of work
>          */
>         public Callable[] getCalls() {
>             return new Callable[]{
>                     phase01(),
>                     phase02(),
>                     phase03()
>             };
>         }
>     }
>


Hope this helps,
--
Alexander R. Saint Croix




On Feb 12, 2008 8:22 AM, Jack Cox <jcox@captechventures.com> wrote:

>
> Is there a way in the 'out-of-container' testing paradigm with openejb for
> the unit test method to control the demarcation of transactions?
>
> Here's the use case:
> 1) The unit test is doing entity bean testing, calling various methods on
> the entity facade to test CRUD operations.
> 2) The unit test needs to demarcate transactions so that it can insert,
> delete, then attempt to retrieve deleted entities.  Of course the last
> retrieval should fail because the entity is deleted.
> 3) But, JPA has the interesting behavior that deleted entities continue to
> be accessible within the deleting transaction.
> 4) Therefore, the unit test needs to demarcate a transaction around the
> delete so that the entity is really removed prior to the last retrieval
> test.
>
> So, how can one demarcate transactions within a junit test case?
>
> Thanks,
>
> Jack
>
> --
> View this message in context:
> http://www.nabble.com/Transactions-controlled-by-Unit-Tests-tp15434029p15434029.html
> Sent from the OpenEJB User mailing list archive at Nabble.com.
>
>

Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message