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

Spring Boot to Micronaut Replace H2 with Real Database for Testing #1313

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions buildSrc/src/main/java/io/spring/start/PostgresqlDriver.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package io.spring.start;

import io.micronaut.core.annotation.NonNull;
import io.micronaut.starter.application.ApplicationType;
import io.micronaut.starter.application.generator.GeneratorContext;
import io.micronaut.starter.build.dependencies.Dependency;
import io.micronaut.starter.feature.Feature;
import jakarta.inject.Singleton;

@Singleton
public class PostgresqlDriver implements Feature {

public static final Dependency DEPENDENCY_POSTGRESQL = Dependency.builder()
.groupId("org.postgresql")
.artifactId("postgresql")
.runtime()
.build();

@Override
public @NonNull String getName() {
return "postgresql-driver";
}

@Override
public boolean supports(ApplicationType applicationType) {
return true;
}

@Override
public String getDescription() {
return "A JDBC and R2DBC driver that allows Java programs to connect to a PostgreSQL database using standard, database independent Java code.";
}

@Override
public String getTitle() {
return "PostgreSQL Driver";
}

@Override
public void apply(GeneratorContext generatorContext) {
generatorContext.addDependency(DEPENDENCY_POSTGRESQL);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ public final class SpringBootDependencies {
public static final String GROUP_ID_ORG_SPRINGFRAMEWORK_BOOT = "org.springframework.boot";
private static final String ARTIFACT_ID_SPRING_BOOT_STARTER = "spring-boot-starter";
private static final String ARTIFACT_ID_SPRING_BOOT_STARTER_WEB = "spring-boot-starter-web";

private static final String ARTIFACT_ID_SPRING_BOOT_STARTER_DATA_JPA = "spring-boot-starter-data-jpa";
private static final String ARTIFACT_ID_SPRING_BOOT_STARTER_TEST = "spring-boot-starter-test";

public static final Dependency.Builder DEPENDENCY_SPRINGBOOT_STARTER = Dependency.builder()
Expand All @@ -32,6 +34,11 @@ public final class SpringBootDependencies {
.groupId(GROUP_ID_ORG_SPRINGFRAMEWORK_BOOT)
.artifactId(ARTIFACT_ID_SPRING_BOOT_STARTER_WEB)
.compile();

public static final Dependency.Builder DEPENDENCY_SPRING_BOOT_STARTER_DATA_JPA = Dependency.builder()
.groupId(GROUP_ID_ORG_SPRINGFRAMEWORK_BOOT)
.artifactId(ARTIFACT_ID_SPRING_BOOT_STARTER_DATA_JPA)
.compile();
public static final Dependency.Builder DEPENDENCY_SPRINGBOOT_STARTER_TEST = Dependency.builder()
.groupId(GROUP_ID_ORG_SPRINGFRAMEWORK_BOOT)
.artifactId(ARTIFACT_ID_SPRING_BOOT_STARTER_TEST)
Expand Down
51 changes: 51 additions & 0 deletions buildSrc/src/main/java/io/spring/start/SpringBootStarterJpa.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
* Copyright 2017-2023 original authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.spring.start;

import io.micronaut.core.annotation.NonNull;
import io.micronaut.starter.application.generator.GeneratorContext;
import jakarta.inject.Singleton;

import static io.spring.start.SpringBootDependencies.*;

@Singleton
public class SpringBootStarterJpa implements SpringBootStarterFeature {
public static final String NAME = "spring-boot-starter-data-jpa";

@Override
@NonNull
public String getName() {
return NAME;
}

@Override
public String getTitle() {
return "Spring Data JPA";
}

@Override
@NonNull
public String getDescription() {
return "Persist data in SQL stores with Java Persistence API using Spring Data and Hibernate.";
}

@Override
public void apply(GeneratorContext generatorContext) {
generatorContext.addDependency(DEPENDENCY_SPRING_BOOT_STARTER_DATA_JPA);
generatorContext.addDependency(DEPENDENCY_SPRINGBOOT_STARTER_TEST);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package io.spring.start;

import io.micronaut.core.annotation.NonNull;
import io.micronaut.starter.application.ApplicationType;
import io.micronaut.starter.application.generator.GeneratorContext;
import io.micronaut.starter.build.dependencies.Dependency;
import io.micronaut.starter.feature.Feature;
import io.micronaut.starter.feature.FeatureContext;
import io.micronaut.starter.feature.database.PostgreSQL;
import jakarta.inject.Singleton;

@Singleton
public class SpringBootTestcontainers implements Feature {

public static final Dependency DEPENDENCY_SPRINGBOOT_TESTCONTAINERS = Dependency.builder()
.groupId(SpringBootDependencies.GROUP_ID_ORG_SPRINGFRAMEWORK_BOOT)
.artifactId("spring-boot-testcontainers")
.test()
.build();

public static final Dependency DEPENDENCY_TESTCONTAINERS_POSTGRESQL = Dependency.builder()
.groupId("org.testcontainers")
.artifactId("postgresql")
.test()
.build();

private final TestContainersJunitJupiter testContainersJunitJupiter;

public SpringBootTestcontainers(TestContainersJunitJupiter testContainersJunitJupiter) {
this.testContainersJunitJupiter = testContainersJunitJupiter;
}

@Override
public void processSelectedFeatures(FeatureContext featureContext) {
featureContext.addFeatureIfNotPresent(TestContainersJunitJupiter.class, testContainersJunitJupiter);
}

@Override
public @NonNull String getName() {
return "spring-boot-testcontainers";
}

@Override
public boolean supports(ApplicationType applicationType) {
return true;
}

@Override
public void apply(GeneratorContext generatorContext) {
generatorContext.addDependency(DEPENDENCY_SPRINGBOOT_TESTCONTAINERS);
if (generatorContext.hasFeature(PostgresqlDriver.class)) {
generatorContext.addDependency(DEPENDENCY_TESTCONTAINERS_POSTGRESQL);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package io.spring.start;

import io.micronaut.core.annotation.NonNull;
import io.micronaut.starter.application.ApplicationType;
import io.micronaut.starter.application.generator.GeneratorContext;
import io.micronaut.starter.build.dependencies.Dependency;
import io.micronaut.starter.feature.Feature;
import jakarta.inject.Singleton;

@Singleton
public class TestContainersJunitJupiter implements Feature {
public static final Dependency DEPENDENCY_TESTCONTAINERS_JUNIT_JUPITER = Dependency.builder()
.groupId("org.testcontainers")
.artifactId("junit-jupiter")
.test()
.build();
@Override
public @NonNull String getName() {
return "testcontainers-junit-jupiter";
}

@Override
public boolean supports(ApplicationType applicationType) {
return true;
}

@Override
public void apply(GeneratorContext generatorContext) {
generatorContext.addDependency(DEPENDENCY_TESTCONTAINERS_JUNIT_JUPITER);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"title": "Replace H2 with a real database for testing - Spring Boot to Micronaut Framework",
"intro": "This guide shows compares how replace H2 with a real database for testing in a Spring Boot application vs a Micronaut Framework application.",
"authors": ["Sergio del Amo"],
"tags": ["spring-boot"],
"categories": ["Spring Boot to Micronaut Framework"],
"publicationDate": "2023-08-01",
"languages": ["java"],
"apps": [
{
"framework": "Spring Boot",
"testFramework": "junit",
"name": "springboot",
"features": ["spring-boot-starter-data-jpa", "postgresql-driver", "testcontainers-junit-jupiter", "spring-boot-testcontainers", "assertj"]
},
{
"name": "micronautframework",
"features": ["data-jpa", "testcontainers", "assertj", "postgresql"]
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package example.micronaut;

import java.util.List;

import jakarta.inject.Singleton;
import org.springframework.jdbc.core.JdbcTemplate;
@Singleton
public class JdbcProductRepository {

private final JdbcTemplate jdbcTemplate;

public JdbcProductRepository(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}

public List<Product> getAllProducts() {

return jdbcTemplate.query(
"select id, code, name from products",
(rs, rowNum) -> {
long id = rs.getLong("id");
String code = rs.getString("code");
String name = rs.getString("name");
return new Product(id, code, name);
}
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package example.micronaut;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Table;

@Entity
@Table(name = "products")
public class Product {

@Id
private Long id;

@Column(nullable = false, unique = true)
private String code;

@Column(nullable = false)
private String name;

public Product() {}

public Product(Long id, String code, String name) {
this.id = id;
this.code = code;
this.name = name;
}

public Long getId() {
return id;
}

public void setId(Long id) {
this.id = id;
}

public String getCode() {
return code;
}

public void setCode(String code) {
this.code = code;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package example.micronaut;

import io.micronaut.context.annotation.Parameter;
import io.micronaut.data.annotation.Query;
import io.micronaut.data.annotation.Repository;
import io.micronaut.data.repository.CrudRepository;

@Repository
interface ProductRepository extends CrudRepository<Product, Long> {
@Query(
value = """
insert into products(id, code, name)
values(:#{#p.id}, :#{#p.code}, :#{#p.name})
ON CONFLICT DO NOTHING
""",
nativeQuery = true
)
void createProductIfNotExists(@Parameter("p") Product product);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
micronaut.application.name=micronautguide
datasources.default.db-type=postgres
datasources.default.dialect=POSTGRES
datasources.default.driver-class-name=org.postgresql.Driver
datasources.default.url=jdbc\:postgresql\://localhost\:5432/postgres
datasources.default.password=
datasources.default.username=postgres
jpa.default.properties.hibernate.hbm2ddl.auto=update
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<configuration>

<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<!-- encoders are assigned the type
ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>

<root level="info">
<appender-ref ref="STDOUT" />
</root>
</configuration>
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package example.micronaut;

import static org.junit.jupiter.api.Assertions.assertEquals;

import java.net.URL;
import java.util.List;
import java.util.Optional;

import io.micronaut.context.annotation.Property;
import io.micronaut.core.io.ResourceLoader;
import io.micronaut.test.extensions.junit5.annotation.MicronautTest;
import jakarta.inject.Inject;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.jdbc.core.JdbcTemplate;

@MicronautTest
@Property(name = "datasources.default.driver-class-name", value = "org.testcontainers.jdbc.ContainerDatabaseDriver")
@Property(name = "datasources.default.url", value = "jdbc:tc:postgresql:15.2-alpine:///db?TC_INITSCRIPT=sql/init-db.sql")
class JdbcProductRepositoryTest {

@Inject
private JdbcTemplate jdbcTemplate;

@Inject
ResourceLoader resourceLoader;

@Inject
JdbcProductRepository productRepository;

@BeforeEach
void setUp() {
//Optional<URL> resource = resourceLoader.getResource("sql/seed-data.sql");
String foo = "";
}

@Test
//@Sql("/sql/seed-data.sql")
void shouldGetAllProducts() {
List<Product> products = productRepository.getAllProducts();
assertEquals(2, products.size());
}
}
Loading