Mocking PersistenceContext

2,019 views
Skip to first unread message

Shriram Shrikumar

unread,
Feb 12, 2013, 6:00:11 AM2/12/13
to cdi-...@googlegroups.com
Hello,

Firstly, thanks for a great tool. It makes testing so much easier. 

Injecting mocks works well. However, I would like to mock other resources like PersistenceContext(s). Is this possible?

Thanks,

Shri

bryn

unread,
Feb 12, 2013, 6:56:49 AM2/12/13
to cdi-...@googlegroups.com
Hi Shri,

I'm glad you find CDI-Unit useful.

It may be a little difficult to mock the persistence context if you are not using @Inject as @PersistenceContext is not part of CDI. In Seam 3 they worked around this and they also did something similar in Deltaspike, but if you are not using something similar you may be out of luck.

If you are using @Inject to get your EntityManager then you can use an H2 database to create an in memory database on the fly for unit testing.

Below is an example utility class that I have used to test code that relies on a database. It is using Seam3, but the same principals can be applied elsewhere. When I want to use database functionality I simply reference this class using @AdditionalClasses on my test class.

Sorry I can't give you anything more specific as it very much depends on your setup.

Bryn

@ApplicationScoped
@AdditionalClasses(value = { TransactionInterceptor.class, TransactionExtension.class, TransactionScopeExtension.class, org.jboss.seam.transaction.EntityTransaction.class,
        SeSynchronizations.class, HibernateManagedSessionExtension.class, ManagedPersistenceContextExtension.class, PersistenceContextsImpl.class, FlushModeManagerImpl.class })
public class H2DatabaseTest {

    private Logger log = LoggerFactory.getLogger(H2DatabaseTest.class);

    private EntityManagerFactory entityManagerFactory;

    @Inject
    private BeanManager beanManager;

    @ExtensionManaged
    @Produces
    @ApplicationScoped
    public EntityManagerFactory getEntityManager() throws IOException {
        return entityManagerFactory;
    }

    @PostConstruct
    public void postConstruct() throws IOException {
        //Create our entity manager for the test
        if (entityManagerFactory != null) {
            throw new RuntimeException("Error");
        }
        Properties properties = new Properties();
        //This properties file configures h2 for in memory operation.
        properties.load(ClassLoader.getSystemResourceAsStream("h2test.properties"));
     
        //Scan the classpath for entities and configure hibernate accordingly
        Ejb3Configuration configuration = new Ejb3Configuration();
        Set<Bean<?>> beans = beanManager.getBeans(Object.class);
        for (Bean<?> bean : beans) {
            Class<?> beanClass = bean.getBeanClass();
            if (beanClass.getAnnotation(Entity.class) != null || beanClass.getAnnotation(Embeddable.class) != null) {
                log.debug("Registering entity {}", beanClass);
                configuration.addAnnotatedClass(beanClass);
            }
        }

        entityManagerFactory = configuration.createEntityManagerFactory(properties);
    }

    @PreDestroy
    public void preDestroy() throws IOException {
        //H2 in memory databases are stored per JVM, so we have to clear it out at the end of each test.
        EntityManager entityManager = entityManagerFactory.createEntityManager();
        Query drop = entityManager.createNativeQuery("DROP ALL OBJECTS");
        EntityTransaction transaction = entityManager.getTransaction();

        transaction.begin();
        entityManager.flush();
        drop.executeUpdate();
        transaction.commit();
        entityManager.close();
        entityManagerFactory.close();
--
You received this message because you are subscribed to the Google Groups "CDI-Unit" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cdi-unit+u...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Shriram Shrikumar

unread,
Feb 25, 2013, 5:54:41 AM2/25/13
to cdi-...@googlegroups.com
Thanks Bryn,

I am using seam and did use the @Inject mechanism for getting the persistence context in there and that works without issues.

Does this mean that we are limited to testing injection via the @Inject annotation?

Also, I have recently come across JMockIt. Do you have any experience with it. As I understand it, it may provide an alternative mechanism for injecting mocks.

I am currently using Mockito so CDI-Unit fits in with that framework without requiring me to migrate a whole bunch of unit tests.

Thanks for the fantasic library :-D


Shri

bryn

unread,
Feb 27, 2013, 7:02:24 AM2/27/13
to cdi-...@googlegroups.com
Hi Shri,

Yes testing is limited to @Inject fields and methods. I have never needed anything else though as dependency injection inherently makes code more testable.

JMockit looks interesting, I'll have to give it a go.

Bryn
Reply all
Reply to author
Forward
0 new messages