1

I have two classes out of which I want to use only one class at run-time (depending on if I am running tests or executing the app on a server(local or otherwise)) and exclude the other from Spring's Component Scanning.

Here the 1st class which I want to use when testing:

public class HibernateUtilForH2 implements HibernateUtil {
private static SessionFactory sessionFactory;
static {
    try {
        Configuration configuration = new Configuration().configure("hibernate.cfg.xml.h2");
        StandardServiceRegistryBuilder builder = new StandardServiceRegistryBuilder()
                .applySettings(configuration.getProperties());
        sessionFactory = configuration.buildSessionFactory(builder.build());

    } catch (Exception ex) {
        throw new ExceptionInInitializerError(ex);
    }
}

public Session openSession() {
    return sessionFactory.openSession();
    }
}

Here's the second class for usage during production or local execution:

public class HibernateUtilForMySql implements HibernateUtil {

private static final SessionFactory sessionFactory;
static {
    try {
        Configuration configuration = new Configuration().configure();
        StandardServiceRegistryBuilder builder = new StandardServiceRegistryBuilder()
                .applySettings(configuration.getProperties());
        sessionFactory = configuration.buildSessionFactory(builder.build());

    } catch (Exception ex) {
        throw new ExceptionInInitializerError(ex);
    }
}

HibernateUtil here is an interface containing declaration of openSession() method only.

I want HibernateUtilForH2 to be injected using DI when testing and HibernateUtilForMySql to be used for production or execution on a local server. How do I do that?

I've tried using @TestComponent and @ConditionalOnWebApplication but neither seems to work. I need a solution that is compatible with GitLab's CI/CD setup so that deployments can be smooth and hassle-free.

Akshay Singh
  • 93
  • 10

1 Answers1

3

You could work with profiles.

Annotate your integration test with @ActiveProfiles("test") and your component that should be loaded for integration tests with @Profile("test") and the Components that should not be loaded for integration tests with @Profile("!test")

Yannic Bürgmann
  • 6,301
  • 5
  • 43
  • 77
  • I feel so stupid now...this worked like a charm. Thanks @Yannic – Akshay Singh Nov 29 '17 at 12:59
  • Glad it worked for you. But try to keep the beans only required for testing to a minimum, since this could become really messy. In addition every @Profile annotation needs to be evaluated at startup of your application which causes a slower startup (EVEN IN PRODUCTION!) – Yannic Bürgmann Nov 29 '17 at 14:21
  • Noted. In any case, the above mentioned classes are the only ones that require profiling. The rest of them are required either way. – Akshay Singh Nov 29 '17 at 19:30