Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clarify documentation on importing Testcontainer declarations and using @ServiceConnection or @DynamicPropertySource #35629

Closed
sergey-morenets opened this issue May 25, 2023 · 5 comments
Assignees
Labels
type: documentation A documentation update
Milestone

Comments

@sergey-morenets
Copy link

sergey-morenets commented May 25, 2023

Hi

We tried to use Spring Boot & TestContainers integration added in Spring Boot 3.1.0.

We used example from the reference documentation:

public interface MyContainers {

    @Container
    MongoDBContainer mongoContainer = new MongoDBContainer("mongo:5.0");

    @Container
    Neo4jContainer<?> neo4jContainer = new Neo4jContainer<>("neo4j:5");

}

So we created an interface with our container declaration:

public interface ProjectContainers {

	@Container
	GenericContainer<?> mysql = new MySQLContainer("mysql:8");

}

Then we created class-configuration:

@TestConfiguration(proxyBeanMethods = false)
@ImportTestcontainers(ProjectContainers.class)
public class ContainerConfiguration {
}

and finally our integration test:

@SpringBootTest(classes = ContainerConfiguration.class)
@Testcontainers
public class OrderServiceTest {

	@Autowired
	OrderService orderService;

	@Test
	void save_success() {
		Order order = new Order();
		orderService.save(order);
	}

However our test failed with exception:

Caused by: org.hibernate.HibernateException: Unable to determine Dialect without JDBC metadata (please set 'javax.persistence.jdbc.url', 'hibernate.connection.url', or 'hibernate.dialect')
	at org.hibernate.engine.jdbc.dialect.internal.DialectFactoryImpl.determineDialect(DialectFactoryImpl.java:188) ~[hibernate-core-6.2.2.Final.jar:6.2.2.Final]
	at org.hibernate.engine.jdbc.dialect.internal.DialectFactoryImpl.buildDialect(DialectFactoryImpl.java:87) ~[hibernate-core-6.2.2.Final.jar:6.2.2.Final]
	at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:274) ~[hibernate-core-6.2.2.Final.jar:6.2.2.Final]
	at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:34) ~[hibernate-core-6.2.2.Final.jar:6.2.2.Final]
	at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.initiateService(StandardServiceRegistryImpl.java:119) ~[hibernate-core-6.2.2.Final.jar:6.2.2.Final]
	at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:264) ~[hibernate-core-6.2.2.Final.jar:6.2.2.Final]
@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label May 25, 2023
@eddumelendez
Copy link
Contributor

Use MySQLContainer<?> mysql = new MySQLContainer<>("mysql:8"); and add @ServiceConnection. Look at the tip at the end of https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#features.testing.testcontainers.at-development-time.importing-container-declarations

@sergey-morenets
Copy link
Author

sergey-morenets commented May 25, 2023

Hi @eddumelendez

Thank you for the quick response. You're correct. Adding @ServiceConnection resolves this issue. However I guess adding code that already has @ServiceConnection makes code examples more obvious and clear.

The same relates to declaring containers as Spring beans. Here's an example from the documentation:

@TestConfiguration(proxyBeanMethods = false)
public class MyContainersConfiguration {

    @Bean
    public MongoDBContainer monogDbContainer(DynamicPropertyRegistry properties) {
        MongoDBContainer container = new MongoDBContainer("mongo:5.0");
        properties.add("spring.data.mongodb.host", container::getHost);
        properties.add("spring.data.mongodb.port", container::getFirstMappedPort);
        return container;
    }
}

The documentation states that "A typical configuration would look like this". However Spring Boot fails to use it because it doesn't have @ServiceConnection annotation on the bean declaration.

@eddumelendez
Copy link
Contributor

eddumelendez commented May 25, 2023

Are you using it at development time just like the docs state? If no, keep using

@DynamicPropertySource
static void properties(DynamicPropertyRegistry registry) {
        registry.add("spring.data.mongodb.host", container::getHost);
        registry.add("spring.data.mongodb.port", container::getFirstMappedPort);
}

I think there is a confusion about the different usage

@wilkinsona
Copy link
Member

In the docs, we don't know how MyContainers will be used. You could make your test class implement MyContainers and then reference those containers in a @DynamicPropertySource. Alternatively, you might need @ServiceConnection. The tip at the end of this section is intended to address that.

That said, this has caused some confusion before so we probably need to do something here, I'm just not quite sure what.

/cc @quaff

@wilkinsona wilkinsona changed the title Failed to import TestContainers declaration classes Clarify documentation on importing Testcontainer declarations and using @ServiceConnection or @DynamicPropertySource May 25, 2023
@wilkinsona wilkinsona added type: documentation A documentation update and removed status: waiting-for-triage An issue we've not yet triaged labels May 25, 2023
@wilkinsona wilkinsona added this to the 3.1.x milestone May 25, 2023
@quaff
Copy link
Contributor

quaff commented May 26, 2023

@wilkinsona I think we should add @ServiceConnection, and add a tip states that it could be removed if @DynamicPropertySource is using.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: documentation A documentation update
Projects
None yet
Development

No branches or pull requests

6 participants