package org.jooby.hbm; import static com.typesafe.config.ConfigValueFactory.fromAnyRef; import static javaslang.Predicates.instanceOf; import static org.easymock.EasyMock.expect; import static org.easymock.EasyMock.isA; import static org.junit.Assert.assertEquals; import java.net.URL; import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.stream.Collectors; import javax.enterprise.inject.spi.BeanManager; import javax.inject.Provider; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.sql.DataSource; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.boot.Metadata; import org.hibernate.boot.MetadataBuilder; import org.hibernate.boot.MetadataSources; import org.hibernate.boot.SessionFactoryBuilder; import org.hibernate.boot.archive.scan.spi.ScanEnvironment; import org.hibernate.boot.model.naming.ImplicitNamingStrategyJpaCompliantImpl; import org.hibernate.boot.registry.BootstrapServiceRegistry; import org.hibernate.boot.registry.BootstrapServiceRegistryBuilder; import org.hibernate.boot.registry.StandardServiceRegistry; import org.hibernate.boot.registry.StandardServiceRegistryBuilder; import org.hibernate.cfg.AvailableSettings; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.event.service.spi.EventListenerRegistry; import org.hibernate.event.spi.EventType; import org.hibernate.event.spi.PostLoadEventListener; import org.hibernate.integrator.spi.Integrator; import org.hibernate.jpa.event.spi.JpaIntegrator; import org.hibernate.service.spi.ServiceRegistryImplementor; import org.jooby.Env; import org.jooby.Env.ServiceKey; import org.jooby.Registry; import org.jooby.internal.hbm.GuiceBeanManager; import org.jooby.internal.hbm.OpenSessionInView; import org.jooby.internal.hbm.ScanEnvImpl; import org.jooby.internal.hbm.SessionProvider; import org.jooby.internal.hbm.UnitOfWorkProvider; import org.jooby.jdbc.Jdbc; import org.jooby.test.MockUnit; import org.jooby.test.MockUnit.Block; import org.junit.Test; import org.junit.runner.RunWith; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; import com.google.common.collect.ImmutableMap; import com.google.inject.Binder; import com.google.inject.Key; import com.google.inject.binder.AnnotatedBindingBuilder; import com.google.inject.binder.LinkedBindingBuilder; import com.google.inject.name.Names; import com.typesafe.config.Config; import com.typesafe.config.ConfigFactory; import com.typesafe.config.ConfigValueFactory; import com.zaxxer.hikari.HikariConfig; import com.zaxxer.hikari.HikariDataSource; import hbm5.Beer; import javaslang.concurrent.Promise; import javaslang.control.Try.CheckedConsumer; import javaslang.control.Try.CheckedRunnable; @RunWith(PowerMockRunner.class) @PrepareForTest({Hbm.class, BootstrapServiceRegistryBuilder.class, JpaIntegrator.class, MetadataSources.class, Promise.class, GuiceBeanManager.class, SessionProvider.class, OpenSessionInView.class }) public class HbmTest { private Block bsrb = unit -> { BootstrapServiceRegistryBuilder bsrb = unit.constructor(BootstrapServiceRegistryBuilder.class) .build(); unit.registerMock(BootstrapServiceRegistryBuilder.class, bsrb); JpaIntegrator jpa = unit.constructor(JpaIntegrator.class) .build(); expect(bsrb.applyIntegrator(jpa)).andReturn(bsrb); BootstrapServiceRegistry bsr = unit.mock(BootstrapServiceRegistry.class); unit.registerMock(BootstrapServiceRegistry.class, bsr); expect(bsrb.build()).andReturn(bsr); }; private Block applyDataSource = unit -> { StandardServiceRegistryBuilder ssrb = unit.get(StandardServiceRegistryBuilder.class); expect(ssrb.applySetting(AvailableSettings.DATASOURCE, unit.get(HikariDataSource.class))) .andReturn(ssrb); }; @SuppressWarnings("unchecked") private Block onStart = unit -> { Env env = unit.get(Env.class); expect(env.onStart(unit.capture(CheckedConsumer.class))).andReturn(env); }; private Block onStop = unit -> { Env env = unit.get(Env.class); expect(env.onStop(unit.capture(CheckedRunnable.class))).andReturn(env); expect(env.onStop(isA(CheckedRunnable.class))).andReturn(env); }; @Test public void shouldLoadConfigFromClasspath() { assertEquals(ConfigFactory.parseResources(Hbm.class, "hbm.conf") .withFallback(ConfigFactory.parseResources(Jdbc.class, "jdbc.conf")), new Hbm().config()); } @Test public void newHbm() throws Exception { String url = "jdbc:h2:target/hbm"; new MockUnit(Env.class, Config.class, Binder.class) .expect(props("org.h2.jdbcx.JdbcDataSource", url, "h2.hbm", "sa", "", false)) .expect(hikariConfig()) .expect(hikariDataSource(url)) .expect(serviceKey("hbm")) .expect(env("dev")) .expect(bsrb) .expect(ssrb("update")) .expect(applySettins(ImmutableMap.of( AvailableSettings.SESSION_FACTORY_NAME_IS_JNDI, false, AvailableSettings.SCANNER_DISCOVERY, "class", AvailableSettings.CURRENT_SESSION_CONTEXT_CLASS, "managed"))) .expect(applyDataSource) .expect(metadataSources()) .expect(metadataBuilder()) .expect(sessionFactoryBuilder("hbm")) .expect(beanManager()) .expect(bind(null, SessionFactory.class)) .expect(bind("hbm", SessionFactory.class)) .expect(bind(null, EntityManagerFactory.class)) .expect(bind("hbm", EntityManagerFactory.class)) .expect(sessionProvider()) .expect(bind(null, Session.class, SessionProvider.class)) .expect(bind("hbm", Session.class, SessionProvider.class)) .expect(bind(null, EntityManager.class, SessionProvider.class)) .expect(bind("hbm", EntityManager.class, SessionProvider.class)) .expect(unitOfWork()) .expect(bind(null, UnitOfWork.class, UnitOfWorkProvider.class)) .expect(bind("hbm", UnitOfWork.class, UnitOfWorkProvider.class)) .expect(onStart) .expect(onStop) .run(unit -> { new Hbm() .configure(unit.get(Env.class), config("hbm"), unit.get(Binder.class)); }); } @SuppressWarnings({"unchecked", "rawtypes" }) @Test public void onStart() throws Exception { String url = "jdbc:h2:target/hbm"; new MockUnit(Env.class, Config.class, Binder.class, Registry.class) .expect(props("org.h2.jdbcx.JdbcDataSource", url, "h2.hbm", "sa", "", false)) .expect(hikariConfig()) .expect(hikariDataSource(url)) .expect(serviceKey("hbm")) .expect(env("dev")) .expect(bsrb) .expect(ssrb("update")) .expect(applySettins(ImmutableMap.of( AvailableSettings.SESSION_FACTORY_NAME_IS_JNDI, false, AvailableSettings.SCANNER_DISCOVERY, "class", AvailableSettings.CURRENT_SESSION_CONTEXT_CLASS, "managed"))) .expect(applyDataSource) .expect(metadataSources()) .expect(metadataBuilder()) .expect(sessionFactoryBuilder("hbm")) .expect(beanManager()) .expect(bind(null, SessionFactory.class)) .expect(bind("hbm", SessionFactory.class)) .expect(bind(null, EntityManagerFactory.class)) .expect(bind("hbm", EntityManagerFactory.class)) .expect(sessionProvider()) .expect(bind(null, Session.class, SessionProvider.class)) .expect(bind("hbm", Session.class, SessionProvider.class)) .expect(bind(null, EntityManager.class, SessionProvider.class)) .expect(bind("hbm", EntityManager.class, SessionProvider.class)) .expect(unitOfWork()) .expect(bind(null, UnitOfWork.class, UnitOfWorkProvider.class)) .expect(bind("hbm", UnitOfWork.class, UnitOfWorkProvider.class)) .expect(onStart) .expect(onStop) .run(unit -> { new Hbm() .configure(unit.get(Env.class), config("hbm"), unit.get(Binder.class)); }, unit -> { CheckedConsumer<Registry> onStart = unit.captured(CheckedConsumer.class).iterator() .next(); onStart.accept(unit.get(Registry.class)); Promise promise = unit.captured(Promise.class).iterator().next(); assertEquals(unit.get(Registry.class), promise.future().get()); }); } @Test public void onStop() throws Exception { String url = "jdbc:h2:target/hbm"; new MockUnit(Env.class, Config.class, Binder.class, Registry.class) .expect(props("org.h2.jdbcx.JdbcDataSource", url, "h2.hbm", "sa", "", false)) .expect(hikariConfig()) .expect(hikariDataSource(url)) .expect(serviceKey("hbm")) .expect(env("dev")) .expect(bsrb) .expect(ssrb("update")) .expect(applySettins(ImmutableMap.of( AvailableSettings.SESSION_FACTORY_NAME_IS_JNDI, false, AvailableSettings.SCANNER_DISCOVERY, "class", AvailableSettings.CURRENT_SESSION_CONTEXT_CLASS, "managed"))) .expect(applyDataSource) .expect(metadataSources()) .expect(metadataBuilder()) .expect(sessionFactoryBuilder("hbm")) .expect(beanManager()) .expect(bind(null, SessionFactory.class)) .expect(bind("hbm", SessionFactory.class)) .expect(bind(null, EntityManagerFactory.class)) .expect(bind("hbm", EntityManagerFactory.class)) .expect(sessionProvider()) .expect(bind(null, Session.class, SessionProvider.class)) .expect(bind("hbm", Session.class, SessionProvider.class)) .expect(bind(null, EntityManager.class, SessionProvider.class)) .expect(bind("hbm", EntityManager.class, SessionProvider.class)) .expect(unitOfWork()) .expect(bind(null, UnitOfWork.class, UnitOfWorkProvider.class)) .expect(bind("hbm", UnitOfWork.class, UnitOfWorkProvider.class)) .expect(onStart) .expect(onStop) .expect(unit -> { unit.get(SessionFactory.class).close(); }) .run(unit -> { new Hbm() .configure(unit.get(Env.class), config("hbm"), unit.get(Binder.class)); }, unit -> { CheckedRunnable onStop = unit.captured(CheckedRunnable.class).iterator() .next(); onStop.run(); }); } @SuppressWarnings({"unchecked", "rawtypes" }) @Test public void withEvent() throws Exception { String url = "jdbc:h2:target/hbm"; new MockUnit(Env.class, Config.class, Binder.class, Registry.class) .expect(props("org.h2.jdbcx.JdbcDataSource", url, "h2.hbm", "sa", "", false)) .expect(hikariConfig()) .expect(hikariDataSource(url)) .expect(serviceKey("hbm")) .expect(env("dev")) .expect(bsrb) .expect(ssrb("update")) .expect(applySettins(ImmutableMap.of( AvailableSettings.SESSION_FACTORY_NAME_IS_JNDI, false, AvailableSettings.SCANNER_DISCOVERY, "class", AvailableSettings.CURRENT_SESSION_CONTEXT_CLASS, "managed"))) .expect(applyDataSource) .expect(metadataSources()) .expect(metadataBuilder()) .expect(sessionFactoryBuilder("hbm")) .expect(beanManager()) .expect(bind(null, SessionFactory.class)) .expect(bind("hbm", SessionFactory.class)) .expect(bind(null, EntityManagerFactory.class)) .expect(bind("hbm", EntityManagerFactory.class)) .expect(sessionProvider()) .expect(bind(null, Session.class, SessionProvider.class)) .expect(bind("hbm", Session.class, SessionProvider.class)) .expect(bind(null, EntityManager.class, SessionProvider.class)) .expect(bind("hbm", EntityManager.class, SessionProvider.class)) .expect(unitOfWork()) .expect(bind(null, UnitOfWork.class, UnitOfWorkProvider.class)) .expect(bind("hbm", UnitOfWork.class, UnitOfWorkProvider.class)) .expect(onStart) .expect(onStop) .expect(unit -> { PostLoadEventListener listener = unit.mock(PostLoadEventListener.class); Registry registry = unit.get(Registry.class); expect(registry.require(PostLoadEventListener.class)) .andReturn(listener); EventListenerRegistry elr = unit.mock(EventListenerRegistry.class); elr.appendListeners(EventType.POST_LOAD, listener); ServiceRegistryImplementor sri = unit.mock(ServiceRegistryImplementor.class); expect(sri.getService(EventListenerRegistry.class)).andReturn(elr); SessionFactoryImplementor sf = unit.get(SessionFactoryImplementor.class); expect(sf.getServiceRegistry()).andReturn(sri); }) .expect(unit -> { AnnotatedBindingBuilder abb = unit.mock(AnnotatedBindingBuilder.class); abb.asEagerSingleton(); Binder binder = unit.get(Binder.class); expect(binder.bind(PostLoadEventListener.class)).andReturn(abb); }) .run(unit -> { new Hbm() .onEvent(EventType.POST_LOAD, PostLoadEventListener.class) .configure(unit.get(Env.class), config("hbm"), unit.get(Binder.class)); }, unit -> { CheckedConsumer<Registry> onStart = unit.captured(CheckedConsumer.class).iterator() .next(); onStart.accept(unit.get(Registry.class)); }); } @Test public void addClass() throws Exception { String url = "jdbc:h2:target/hbm"; new MockUnit(Env.class, Config.class, Binder.class) .expect(props("org.h2.jdbcx.JdbcDataSource", url, "h2.hbm", "sa", "", false)) .expect(hikariConfig()) .expect(hikariDataSource(url)) .expect(serviceKey("hbm")) .expect(env("dev")) .expect(bsrb) .expect(ssrb("update")) .expect(applySettins(ImmutableMap.of( AvailableSettings.SESSION_FACTORY_NAME_IS_JNDI, false, AvailableSettings.SCANNER_DISCOVERY, "class", AvailableSettings.CURRENT_SESSION_CONTEXT_CLASS, "managed"))) .expect(applyDataSource) .expect(metadataSources(Beer.class)) .expect(metadataBuilder()) .expect(sessionFactoryBuilder("hbm")) .expect(beanManager()) .expect(bind(null, SessionFactory.class)) .expect(bind("hbm", SessionFactory.class)) .expect(bind(null, EntityManagerFactory.class)) .expect(bind("hbm", EntityManagerFactory.class)) .expect(sessionProvider()) .expect(bind(null, Session.class, SessionProvider.class)) .expect(bind("hbm", Session.class, SessionProvider.class)) .expect(bind(null, EntityManager.class, SessionProvider.class)) .expect(bind("hbm", EntityManager.class, SessionProvider.class)) .expect(unitOfWork()) .expect(bind(null, UnitOfWork.class, UnitOfWorkProvider.class)) .expect(bind("hbm", UnitOfWork.class, UnitOfWorkProvider.class)) .expect(onStart) .expect(onStop) .run(unit -> { new Hbm() .classes(Beer.class) .configure(unit.get(Env.class), config("hbm"), unit.get(Binder.class)); }); } @Test public void defaultScan() throws Exception { String url = "jdbc:h2:target/hbm"; new MockUnit(Env.class, Config.class, Binder.class) .expect(props("org.h2.jdbcx.JdbcDataSource", url, "h2.hbm", "sa", "", false)) .expect(hikariConfig()) .expect(hikariDataSource(url)) .expect(serviceKey("hbm")) .expect(env("dev")) .expect(bsrb) .expect(ssrb("update")) .expect(applySettins(ImmutableMap.of( AvailableSettings.SESSION_FACTORY_NAME_IS_JNDI, false, AvailableSettings.SCANNER_DISCOVERY, "class", AvailableSettings.CURRENT_SESSION_CONTEXT_CLASS, "managed"))) .expect(applyDataSource) .expect(metadataSources("my.model")) .expect(metadataBuilder()) .expect(sessionFactoryBuilder("hbm")) .expect(beanManager()) .expect(bind(null, SessionFactory.class)) .expect(bind("hbm", SessionFactory.class)) .expect(bind(null, EntityManagerFactory.class)) .expect(bind("hbm", EntityManagerFactory.class)) .expect(sessionProvider()) .expect(bind(null, Session.class, SessionProvider.class)) .expect(bind("hbm", Session.class, SessionProvider.class)) .expect(bind(null, EntityManager.class, SessionProvider.class)) .expect(bind("hbm", EntityManager.class, SessionProvider.class)) .expect(unitOfWork()) .expect(bind(null, UnitOfWork.class, UnitOfWorkProvider.class)) .expect(bind("hbm", UnitOfWork.class, UnitOfWorkProvider.class)) .expect(onStart) .expect(onStop) .run(unit -> { new Hbm() .scan() .configure(unit.get(Env.class), config("hbm"), unit.get(Binder.class)); }); } @Test public void scan() throws Exception { String url = "jdbc:h2:target/hbm"; new MockUnit(Env.class, Config.class, Binder.class) .expect(props("org.h2.jdbcx.JdbcDataSource", url, "h2.hbm", "sa", "", false)) .expect(hikariConfig()) .expect(hikariDataSource(url)) .expect(serviceKey("hbm")) .expect(env("dev")) .expect(bsrb) .expect(ssrb("update")) .expect(applySettins(ImmutableMap.of( AvailableSettings.SESSION_FACTORY_NAME_IS_JNDI, false, AvailableSettings.SCANNER_DISCOVERY, "class", AvailableSettings.CURRENT_SESSION_CONTEXT_CLASS, "managed"))) .expect(applyDataSource) .expect(metadataSources("my.model")) .expect(metadataBuilder()) .expect(sessionFactoryBuilder("hbm")) .expect(beanManager()) .expect(bind(null, SessionFactory.class)) .expect(bind("hbm", SessionFactory.class)) .expect(bind(null, EntityManagerFactory.class)) .expect(bind("hbm", EntityManagerFactory.class)) .expect(sessionProvider()) .expect(bind(null, Session.class, SessionProvider.class)) .expect(bind("hbm", Session.class, SessionProvider.class)) .expect(bind(null, EntityManager.class, SessionProvider.class)) .expect(bind("hbm", EntityManager.class, SessionProvider.class)) .expect(unitOfWork()) .expect(bind(null, UnitOfWork.class, UnitOfWorkProvider.class)) .expect(bind("hbm", UnitOfWork.class, UnitOfWorkProvider.class)) .expect(onStart) .expect(onStop) .run(unit -> { new Hbm() .scan("my.model") .configure(unit.get(Env.class), config("hbm"), unit.get(Binder.class)); }); } @Test public void shouldPickupCustomHibernateProps() throws Exception { String url = "jdbc:h2:target/hbm"; new MockUnit(Env.class, Config.class, Binder.class) .expect(props("org.h2.jdbcx.JdbcDataSource", url, "h2.hbm", "sa", "", false)) .expect(hikariConfig()) .expect(hikariDataSource(url)) .expect(serviceKey("hbm")) .expect(env("dev")) .expect(bsrb) .expect(ssrb("update")) .expect(applySettins(ImmutableMap.of( AvailableSettings.DIALECT, "h2", AvailableSettings.SESSION_FACTORY_NAME_IS_JNDI, false, AvailableSettings.SCANNER_DISCOVERY, "class", AvailableSettings.CURRENT_SESSION_CONTEXT_CLASS, "managed"))) .expect(applyDataSource) .expect(metadataSources()) .expect(metadataBuilder()) .expect(sessionFactoryBuilder("hbm")) .expect(beanManager()) .expect(bind(null, SessionFactory.class)) .expect(bind("hbm", SessionFactory.class)) .expect(bind(null, EntityManagerFactory.class)) .expect(bind("hbm", EntityManagerFactory.class)) .expect(sessionProvider()) .expect(bind(null, Session.class, SessionProvider.class)) .expect(bind("hbm", Session.class, SessionProvider.class)) .expect(bind(null, EntityManager.class, SessionProvider.class)) .expect(bind("hbm", EntityManager.class, SessionProvider.class)) .expect(unitOfWork()) .expect(bind(null, UnitOfWork.class, UnitOfWorkProvider.class)) .expect(bind("hbm", UnitOfWork.class, UnitOfWorkProvider.class)) .expect(onStart) .expect(onStop) .run(unit -> { new Hbm() .configure(unit.get(Env.class), config("hbm").withValue("hibernate.dialect", ConfigValueFactory.fromAnyRef("h2")), unit.get(Binder.class)); }); } @Test public void ddlAutoIsNoneOnProd() throws Exception { String url = "jdbc:h2:target/hbm"; new MockUnit(Env.class, Config.class, Binder.class) .expect(props("org.h2.jdbcx.JdbcDataSource", url, "h2.hbm", "sa", "", false)) .expect(hikariConfig()) .expect(hikariDataSource(url)) .expect(serviceKey("hbm")) .expect(env("prod")) .expect(bsrb) .expect(ssrb("none")) .expect(applySettins(ImmutableMap.of( AvailableSettings.SESSION_FACTORY_NAME_IS_JNDI, false, AvailableSettings.SCANNER_DISCOVERY, "class", AvailableSettings.CURRENT_SESSION_CONTEXT_CLASS, "managed"))) .expect(applyDataSource) .expect(metadataSources()) .expect(metadataBuilder()) .expect(sessionFactoryBuilder("hbm")) .expect(beanManager()) .expect(bind(null, SessionFactory.class)) .expect(bind("hbm", SessionFactory.class)) .expect(bind(null, EntityManagerFactory.class)) .expect(bind("hbm", EntityManagerFactory.class)) .expect(sessionProvider()) .expect(bind(null, Session.class, SessionProvider.class)) .expect(bind("hbm", Session.class, SessionProvider.class)) .expect(bind(null, EntityManager.class, SessionProvider.class)) .expect(bind("hbm", EntityManager.class, SessionProvider.class)) .expect(unitOfWork()) .expect(bind(null, UnitOfWork.class, UnitOfWorkProvider.class)) .expect(bind("hbm", UnitOfWork.class, UnitOfWorkProvider.class)) .expect(onStart) .expect(onStop) .run(unit -> { new Hbm() .configure(unit.get(Env.class), config("hbm"), unit.get(Binder.class)); }); } @Test public void genericSetupCallbackShouldWork() throws Exception { String url = "jdbc:h2:target/hbm"; new MockUnit(Env.class, Config.class, Binder.class, Integrator.class) .expect(props("org.h2.jdbcx.JdbcDataSource", url, "h2.hbm", "sa", "", false)) .expect(hikariConfig()) .expect(hikariDataSource(url)) .expect(serviceKey("hbm")) .expect(env("prod")) .expect(bsrb) .expect(ssrb("none")) .expect(applySettins(ImmutableMap.of( AvailableSettings.SESSION_FACTORY_NAME_IS_JNDI, false, AvailableSettings.SCANNER_DISCOVERY, "class", AvailableSettings.CURRENT_SESSION_CONTEXT_CLASS, "managed"))) .expect(applyDataSource) .expect(metadataSources()) .expect(metadataBuilder()) .expect(sessionFactoryBuilder("hbm")) .expect(beanManager()) .expect(bind(null, SessionFactory.class)) .expect(bind("hbm", SessionFactory.class)) .expect(bind(null, EntityManagerFactory.class)) .expect(bind("hbm", EntityManagerFactory.class)) .expect(sessionProvider()) .expect(bind(null, Session.class, SessionProvider.class)) .expect(bind("hbm", Session.class, SessionProvider.class)) .expect(bind(null, EntityManager.class, SessionProvider.class)) .expect(bind("hbm", EntityManager.class, SessionProvider.class)) .expect(unitOfWork()) .expect(bind(null, UnitOfWork.class, UnitOfWorkProvider.class)) .expect(bind("hbm", UnitOfWork.class, UnitOfWorkProvider.class)) .expect(onStart) .expect(onStop) .expect(unit -> { BootstrapServiceRegistryBuilder bsrb = unit.get(BootstrapServiceRegistryBuilder.class); expect(bsrb.applyIntegrator(unit.get(Integrator.class))).andReturn(bsrb); }) .run(unit -> { new Hbm() .doWith((final BootstrapServiceRegistryBuilder bsrb) -> { bsrb.applyIntegrator(unit.get(Integrator.class)); }) .configure(unit.get(Env.class), config("hbm"), unit.get(Binder.class)); }); } @Test(expected = ClassCastException.class) public void genericSetupCallbackShouldReportClassCastException() throws Exception { String url = "jdbc:h2:target/hbm"; new MockUnit(Env.class, Config.class, Binder.class, Integrator.class) .expect(props("org.h2.jdbcx.JdbcDataSource", url, "h2.hbm", "sa", "", false)) .expect(hikariConfig()) .expect(hikariDataSource(url)) .expect(serviceKey("hbm")) .expect(env("prod")) .expect(bsrb) .expect(ssrb("none")) .expect(applySettins(ImmutableMap.of( AvailableSettings.SESSION_FACTORY_NAME_IS_JNDI, false, AvailableSettings.SCANNER_DISCOVERY, "class", AvailableSettings.CURRENT_SESSION_CONTEXT_CLASS, "managed"))) .expect(applyDataSource) .expect(metadataSources()) .expect(metadataBuilder()) .expect(sessionFactoryBuilder("hbm")) .expect(beanManager()) .expect(bind(null, SessionFactory.class)) .expect(bind("hbm", SessionFactory.class)) .expect(bind(null, EntityManagerFactory.class)) .expect(bind("hbm", EntityManagerFactory.class)) .expect(sessionProvider()) .expect(bind(null, Session.class, SessionProvider.class)) .expect(bind("hbm", Session.class, SessionProvider.class)) .expect(bind(null, EntityManager.class, SessionProvider.class)) .expect(bind("hbm", EntityManager.class, SessionProvider.class)) .expect(unitOfWork()) .expect(bind(null, UnitOfWork.class, UnitOfWorkProvider.class)) .expect(bind("hbm", UnitOfWork.class, UnitOfWorkProvider.class)) .expect(onStart) .expect(onStop) .run(unit -> { new Hbm() .doWith((final BootstrapServiceRegistryBuilder bsrb) -> { Object value = ""; System.out.println(((Number) value).intValue()); }) .configure(unit.get(Env.class), config("hbm"), unit.get(Binder.class)); }); } @Test(expected = NullPointerException.class) public void genericSetupCallbackShouldReportException() throws Exception { String url = "jdbc:h2:target/hbm"; new MockUnit(Env.class, Config.class, Binder.class, Integrator.class) .expect(props("org.h2.jdbcx.JdbcDataSource", url, "h2.hbm", "sa", "", false)) .expect(hikariConfig()) .expect(hikariDataSource(url)) .expect(serviceKey("hbm")) .expect(env("prod")) .expect(bsrb) .expect(ssrb("none")) .expect(applySettins(ImmutableMap.of( AvailableSettings.SESSION_FACTORY_NAME_IS_JNDI, false, AvailableSettings.SCANNER_DISCOVERY, "class", AvailableSettings.CURRENT_SESSION_CONTEXT_CLASS, "managed"))) .expect(applyDataSource) .expect(metadataSources()) .expect(metadataBuilder()) .expect(sessionFactoryBuilder("hbm")) .expect(beanManager()) .expect(bind(null, SessionFactory.class)) .expect(bind("hbm", SessionFactory.class)) .expect(bind(null, EntityManagerFactory.class)) .expect(bind("hbm", EntityManagerFactory.class)) .expect(sessionProvider()) .expect(bind(null, Session.class, SessionProvider.class)) .expect(bind("hbm", Session.class, SessionProvider.class)) .expect(bind(null, EntityManager.class, SessionProvider.class)) .expect(bind("hbm", EntityManager.class, SessionProvider.class)) .expect(unitOfWork()) .expect(bind(null, UnitOfWork.class, UnitOfWorkProvider.class)) .expect(bind("hbm", UnitOfWork.class, UnitOfWorkProvider.class)) .expect(onStart) .expect(onStop) .run(unit -> { new Hbm() .doWith((final SessionFactory bsrb) -> { throw new NullPointerException(); }) .configure(unit.get(Env.class), config("hbm"), unit.get(Binder.class)); }); } @Test public void newHbmWithDbProp() throws Exception { String url = "jdbc:h2:target/hbm"; new MockUnit(Env.class, Config.class, Binder.class) .expect(props("org.h2.jdbcx.JdbcDataSource", url, "h2.hbm", "sa", "", false)) .expect(hikariConfig()) .expect(hikariDataSource(url)) .expect(serviceKey("hbm")) .expect(env("dev")) .expect(bsrb) .expect(ssrb("update")) .expect(applySettins(ImmutableMap.of( AvailableSettings.SESSION_FACTORY_NAME_IS_JNDI, false, AvailableSettings.SCANNER_DISCOVERY, "class", AvailableSettings.CURRENT_SESSION_CONTEXT_CLASS, "managed"))) .expect(applyDataSource) .expect(metadataSources()) .expect(metadataBuilder()) .expect(sessionFactoryBuilder("hbm")) .expect(beanManager()) .expect(bind(null, SessionFactory.class)) .expect(bind("hbm", SessionFactory.class)) .expect(bind(null, EntityManagerFactory.class)) .expect(bind("hbm", EntityManagerFactory.class)) .expect(sessionProvider()) .expect(bind(null, Session.class, SessionProvider.class)) .expect(bind("hbm", Session.class, SessionProvider.class)) .expect(bind(null, EntityManager.class, SessionProvider.class)) .expect(bind("hbm", EntityManager.class, SessionProvider.class)) .expect(unitOfWork()) .expect(bind(null, UnitOfWork.class, UnitOfWorkProvider.class)) .expect(bind("hbm", UnitOfWork.class, UnitOfWorkProvider.class)) .expect(onStart) .expect(onStop) .run(unit -> { new Hbm("db") .configure(unit.get(Env.class), config("hbm"), unit.get(Binder.class)); }); } private Block sessionProvider() { return unit -> { SessionFactory sf = unit.get(SessionFactory.class); SessionProvider sp = unit.constructor(SessionProvider.class) .build(sf); unit.registerMock(SessionProvider.class, sp); }; } private Block unitOfWork() { return unit -> { SessionFactory sf = unit.get(SessionFactory.class); UnitOfWorkProvider sp = unit.constructor(UnitOfWorkProvider.class) .build(sf); unit.registerMock(UnitOfWorkProvider.class, sp); }; } @SuppressWarnings({"rawtypes", "unchecked" }) private Block bind(final String name, final Class type) { return unit -> { LinkedBindingBuilder lbb = unit.mock(LinkedBindingBuilder.class); lbb.toInstance(unit.get(type)); Binder binder = unit.get(Binder.class); Key key = name == null ? Key.get(type) : Key.get(type, Names.named(name)); expect(binder.bind(key)).andReturn(lbb); }; } @SuppressWarnings({"rawtypes", "unchecked" }) private Block bind(final String name, final Class type, final Class<? extends Provider> provider) { return unit -> { LinkedBindingBuilder lbb = unit.mock(LinkedBindingBuilder.class); expect(lbb.toProvider(unit.get(provider))).andReturn(lbb); Binder binder = unit.get(Binder.class); Key key = name == null ? Key.get(type) : Key.get(type, Names.named(name)); expect(binder.bind(key)).andReturn(lbb); }; } @SuppressWarnings("unchecked") private Block beanManager() { return unit -> { unit.mockStatic(GuiceBeanManager.class); BeanManager bm = unit.mock(BeanManager.class); unit.registerMock(BeanManager.class, bm); expect(GuiceBeanManager.beanManager(unit.capture(Promise.class))).andReturn(bm); SessionFactoryBuilder sfb = unit.get(SessionFactoryBuilder.class); expect(sfb.applyBeanManager(bm)).andReturn(sfb); }; } private Block sessionFactoryBuilder(final String name) { return unit -> { SessionFactoryBuilder sfb = unit.get(SessionFactoryBuilder.class); expect(sfb.applyName(name)).andReturn(sfb); SessionFactoryImplementor sf = unit.mock(SessionFactoryImplementor.class); expect(sfb.build()).andReturn(sf); unit.registerMock(SessionFactory.class, sf); unit.registerMock(SessionFactoryImplementor.class, sf); unit.registerMock(EntityManagerFactory.class, sf); }; } private Block metadataBuilder() { return unit -> { MetadataBuilder mb = unit.get(MetadataBuilder.class); expect(mb.applyImplicitNamingStrategy(ImplicitNamingStrategyJpaCompliantImpl.INSTANCE)) .andReturn(mb); expect(mb.applyScanEnvironment(unit.get(ScanEnvironment.class))).andReturn(mb); SessionFactoryBuilder sfb = unit.mock(SessionFactoryBuilder.class); unit.registerMock(SessionFactoryBuilder.class, sfb); Metadata md = unit.mock(Metadata.class); expect(md.getSessionFactoryBuilder()).andReturn(sfb); expect(mb.build()).andReturn(md); unit.registerMock(Metadata.class, md); }; } @SuppressWarnings("rawtypes") private Block metadataSources(final Object... resources) { return unit -> { StandardServiceRegistry ssr = unit.get(StandardServiceRegistry.class); MetadataSources sources = unit.constructor(MetadataSources.class) .build(ssr); unit.registerMock(MetadataSources.class, sources); List<String> packages = Arrays.asList(resources) .stream() .filter(instanceOf(String.class)) .map(s -> s.toString()) .collect(Collectors.toList()); List<Class> classes = Arrays.asList(resources) .stream() .filter(instanceOf(Class.class)) .map(it -> (Class) it) .collect(Collectors.toList()); MetadataBuilder mb = unit.mock(MetadataBuilder.class); unit.registerMock(MetadataBuilder.class, mb); expect(sources.getAnnotatedPackages()).andReturn(packages); expect(sources.getMetadataBuilder()).andReturn(mb); packages.forEach(c -> { expect(sources.addPackage(c)).andReturn(sources); }); classes.forEach(c -> { expect(sources.addAnnotatedClass(c)).andReturn(sources); }); List<URL> urls = packages .stream() .map(pkg -> getClass().getResource("/" + pkg.replace('.', '/'))) .collect(Collectors.toList()); ScanEnvImpl scanenv = unit.constructor(ScanEnvImpl.class) .build(urls); unit.registerMock(ScanEnvironment.class, scanenv); }; } private Block applySettins(final Map<String, Object> settings) { return unit -> { StandardServiceRegistryBuilder ssrb = unit.get(StandardServiceRegistryBuilder.class); expect(ssrb.applySettings(settings)).andReturn(ssrb); expect(ssrb.applySetting(org.hibernate.jpa.AvailableSettings.DELAY_CDI_ACCESS, true)) .andReturn(ssrb); }; } private Block ssrb(final String ddl) { return unit -> { StandardServiceRegistryBuilder ssrb = unit.constructor(StandardServiceRegistryBuilder.class) .build(unit.get(BootstrapServiceRegistry.class)); expect(ssrb.applySetting(AvailableSettings.HBM2DDL_AUTO, ddl)).andReturn(ssrb); StandardServiceRegistry ssr = unit.mock(StandardServiceRegistry.class); unit.registerMock(StandardServiceRegistry.class, ssr); expect(ssrb.build()).andReturn(ssr); unit.registerMock(StandardServiceRegistryBuilder.class, ssrb); }; } private Block env(final String name) { return unit -> { Env env = unit.get(Env.class); expect(env.name()).andReturn(name); }; } private Config config(final String db) { return new Hbm().config() .withValue("db", ConfigValueFactory.fromAnyRef("fs")) .withValue("application.ns", ConfigValueFactory.fromAnyRef("my.model")) .withValue("application.tmpdir", ConfigValueFactory.fromAnyRef("target")) .withValue("application.name", ConfigValueFactory.fromAnyRef(db)) .withValue("application.charset", ConfigValueFactory.fromAnyRef("UTF-8")) .withValue("runtime.processors-x2", fromAnyRef("4")) .resolve(); } @SuppressWarnings("unchecked") private Block serviceKey(final String db) { return unit -> { Env env = unit.get(Env.class); ServiceKey skey = new Env.ServiceKey(); expect(env.serviceKey()).andReturn(skey).times(2); AnnotatedBindingBuilder<DataSource> binding = unit.mock(AnnotatedBindingBuilder.class); binding.toInstance(unit.get(HikariDataSource.class)); binding.toInstance(unit.get(HikariDataSource.class)); Binder binder = unit.get(Binder.class); expect(binder.bind(Key.get(DataSource.class))).andReturn(binding); expect(binder.bind(Key.get(DataSource.class, Names.named(db)))).andReturn(binding); }; } private Block hikariConfig() { return unit -> { Properties properties = unit.get(Properties.class); HikariConfig hikari = unit.constructor(HikariConfig.class) .build(properties); unit.registerMock(HikariConfig.class, hikari); }; } private Block hikariDataSource(final String url) { return unit -> { HikariConfig properties = unit.get(HikariConfig.class); HikariDataSource hikari = unit.constructor(HikariDataSource.class) .build(properties); unit.registerMock(HikariDataSource.class, hikari); }; } private Block props(final String dataSourceClassName, final String url, final String name, final String username, final String password, final boolean hasDataSourceClassName) { return unit -> { Properties properties = unit.constructor(Properties.class) .build(); expect(properties .setProperty("dataSource.dataSourceClassName", dataSourceClassName)) .andReturn(null); if (username != null) { expect(properties .setProperty("dataSource.user", username)) .andReturn(null); expect(properties .setProperty("dataSource.password", password)) .andReturn(null); } expect(properties .setProperty("dataSource.url", url)) .andReturn(null); if (hasDataSourceClassName) { expect(properties.getProperty("dataSourceClassName")).andReturn(dataSourceClassName); } else { expect(properties.getProperty("dataSourceClassName")).andReturn(null); expect(properties.getProperty("dataSource.dataSourceClassName")) .andReturn(dataSourceClassName); expect(properties.setProperty("dataSourceClassName", dataSourceClassName)).andReturn(null); } expect(properties.remove("dataSource.dataSourceClassName")).andReturn(dataSourceClassName); expect(properties.setProperty("poolName", name)).andReturn(null); expect(properties.setProperty("maximumPoolSize", "4")).andReturn(null); unit.registerMock(Properties.class, properties); }; } }