'Spring Boot unit test - override/set a setting with a instance value

Scenario:

  • In my database integration tests I want to count the number of queries that Hibernate send to the database during various flows in my code (and perhaps do other inspections on the executed queries as well).
  • I have implemented a custom StatementInspector that simply saves the statements and in the test I can count and inspect the queries.

In my unit test code I have the following:

@DataJpaTest(properties = {
  "spring.jpa.properties.hibernate.session_factory.statement_inspector=HibernateStatementInspector"
})
public class JPATest {
    @PersistenceContext
    private EntityManager entityManager;

    @Test
    void checkStatementInspector() {
        assertEquals(0, entityManager.createQuery("select a from Author a").getResultList().size());
        assertEquals(0, entityManager.createQuery("select b from Book b").getResultList().size());
        
        assertNull(entityManager.find(Author.class, 1L));

        var statements = HibernateStatementInspector.getStatements();
        for (var statement: statements) {
            System.out.println(statement);
        }
    }
}

public class HibernateStatementInspector implements StatementInspector {
    static private final ArrayList<String> statements = new ArrayList<>();

    static public List<String> getStatements() {
        return statements;
    }

    @Override
    public String inspect(String s) {
        statements.add(s);
        return s;
    }
}

The hibernate docs say:

hibernate.session_factory.statement_inspector (e.g. A fully-qualified class name, an instance, or a Class object reference) Names a StatementInspector implementation to be applied to every Session created by the current SessionFactory.

Can reference a StatementInspector instance, StatementInspector implementation Class reference or StatementInspector implementation class name (fully-qualified class name).

Questions/issues:

  • Currently I specify the fully-qualified class name, so Spring creates an instance and the statements are stored in a static ArrayList.
  • I would like to do configure the setting using an instance instead, i.e. create an instance of my custom StatementInspector and somehow tell Spring to use the instance (instead of the class name) when running the test.
  • Question: How can I set up the unit test to use an instance value for the spring.jpa.properties.hibernate.session_factory.statement_inspector property?
  • Question: Using the StatementInspector there is AFAIK no way to get query parameter values used in the queries. How can I get the query parameter values?


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source