vendredi 23 février 2018

Testing ordered CRUD in jUnit

I want to test CRUD operations in my jUnit tests. I'd like to do that in some order, where testCreate would insert the record into the database, and testRead, testUpdate, testDelete would work on the data that testCreate has already inserted. Now I am trying to do something like this.

@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public abstract class UserPersistenceTest {

    @PersistenceContext
    protected EntityManager entityManager;

    @Inject
    protected UserTransaction utx;

    protected Collection<User> entities;

    @Rule
    public ExternalResource resource = new ExternalResource() {
        @Override
        protected void before() throws Exception {
            System.out.println("Setting up resource");
            entities = generateEntities(); // returns a list of User
            prepareTests();
        }
        @Override
        protected void after() {
            System.out.println("Cleaning up resource");
            try {
                utx.rollback();
            } catch (SystemException e) {
                e.printStackTrace();
            }
        }
    };

    @Deployment
    public static Archive<?> createDeployment() {
        return Deployments.createDeployment();
    }

    public void prepareTests() throws Exception {
        utx.begin();

        System.out.println("Inserting records...");

        for (User e : entities) {
            entityManager.persist(e);
        }
    }


    @After
    public void tearDown() throws Exception {
        entityManager.joinTransaction();
    }



    @Test
    public void testCreate() throws Exception {
        // insert records
        for (User e : entities) {
            entityManager.persist(e);
        }

        // validate that they're there
        testRead();
    }


    @Test
    public void testRead() {
        JPAQuery q = new JPAQuery(entityManager);

        List<User> retrieved = q.from(e).list(e);

        Assert.assertEquals(entities.size(), retrieved.size());
        Assert.assertTrue(retrieved.containsAll(entities));
    }

Now the strange thing about it that READ,UPDATE,DELETE test don't work if I don't insert the records prior to the test-cases, ie. method prepareTests(). They simply don't see the inserted records, like there was some sort of automatic rollback. CREATE works. However, if the records are inserted prior to CREATE, everything will work.

My question is, why do other tests not "see" the change that testCreate has done (inserted the records)? I verified that it actually runs before other tests. But they normally see it if before() method inserts them.

What is going on here? How can I make my other tests aware of testCreate is inserting?

Aucun commentaire:

Enregistrer un commentaire