Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I test my DAO update method in an AbstractTransactionalJUnit4SpringContextTests test?

I'm using Java 8, JUnit 4.12, Spring 4, and Hibernate 5.2.12.Final. I want to test a Hibernate method where I update some rows. The method looks like this

        final CriteriaBuilder qb = m_entityManager.getCriteriaBuilder();
        final CriteriaUpdate<FailedEvent> q = qb.createCriteriaUpdate(FailedEvent.class);
        final Root<FailedEvent> root = q.from(FailedEvent.class);
        q.where(qb.and( qb.equal(root.get(FailedEvent_.objectId), objectId) ));
        q.set(root.get(FailedEvent_.flaggedForDelete), true);
        affectedRows = m_entityManager.createQuery(q).executeUpdate();
     return affectedRows > 0;

I have the following JUnit test to verify this

public class FailedEventDaoTest extends AbstractTransactionalJUnit4SpringContextTests
...

    @Test
    public final void testFlagForDeleteByObjectId()
    {
            final String eventId = "testId";
            final FailedEvent event = failedEventDao.findByEventId(eventId);
            Assert.assertFalse("A pre-condition fo this test is that an failed_event record with id \"" + eventId + "\" have a non-empty object id.", StringUtils.isEmpty(event.getObjectId()));
            Assert.assertTrue(failedEventDao.flagForDeleteByObjectId(event.getObjectId()));
            final FailedEvent foundEvent = failedEventDao.findByEventId(eventId);
            Assert.assertTrue("Failed to mark flag for deletion.", foundEvent.getFlaggedForDelete());
    }   // testFlagForDeleteByObjectId

But my test fails on the last line,

Assert.assertTrue("Failed to mark flag for deletion.", foundEvent.getFlaggedForDelete());

Is this because the transaction hasn't completed yet so nothing has been updated in the database? What's the way I can validate that the right records are updated?

like image 977
Dave Avatar asked Feb 25 '19 16:02

Dave


People also ask

How do you test a layer in Dao?

Load the test configuration file before starting test-suite. @ContextConfiguration (locations = "classpath:application-context-test. xml" ); As you have loaded the main configuration as well, you will be easily able to inject DAO references directly into testcase.

What kind of testing can be done in spring test module?

Spring's integration testing support has the following primary goals: To manage Spring IoC container caching between tests. To provide Dependency Injection of test fixture instances. To provide transaction management appropriate to integration testing.

Which annotation is used on an integration test method to run it in a transaction?

@Transaction annotation for integration testing in Spring Boot.

Which annotation will set ApplicationContext for the Test class?

Set the spring ApplicationContext for your test classes using @ContextConfiguration annotation.


1 Answers

Try @AfterTransaction Annotation to test the result.

    @AfterTransaction
    public final void theRealTest()
    {
            Assert.assertTrue("Failed to mark flag for deletion.", foundEvent.getFlaggedForDelete());
    }

https://www.springbyexample.org/examples/simple-spring-transactional-junit4-test-code-example.html

if this is also not working try:

"So, you need to create multiple transactions inside your test method. As you can see, you cannot use AbstractTransactionalJUnit4SpringContextTests, because it creates a single transaction for the whole test method, and cannot use bare AbstractJUnit4SpringContextTests, because it creates no transactions at all.

The solution is to use AbstractJUnit4SpringContextTests and manage transactions inside your test method programmatically.

You need to inject PlatformTransactionManager into your test, create TransactionTemplate from it and use it to demarcate your transactions as described in 11.6 Programmatic transaction management."

found here: Using AbstractTransactionalJUnit4SpringContextTests with commit halfway through

like image 140
DCO Avatar answered Sep 22 '22 06:09

DCO