diff --git a/.run/Test.run.xml b/.run/Test.run.xml
new file mode 100644
index 0000000..e33b35f
--- /dev/null
+++ b/.run/Test.run.xml
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+
+
+
+ true
+ true
+ false
+ false
+
+
+
\ No newline at end of file
diff --git a/.run/WebshopApplication.run.xml b/.run/WebshopApplication.run.xml
index 95e89f9..f043e2d 100644
--- a/.run/WebshopApplication.run.xml
+++ b/.run/WebshopApplication.run.xml
@@ -4,7 +4,6 @@
-
\ No newline at end of file
diff --git a/build.gradle.kts b/build.gradle.kts
index 81a75ba..cb4a894 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -27,6 +27,9 @@ dependencies {
implementation("org.springframework.boot:spring-boot-starter-data-jpa")
implementation("org.springframework.boot:spring-boot-starter-web")
implementation("org.springframework.boot:spring-boot-starter-validation")
+ testImplementation("org.testcontainers:junit-jupiter")
+ testImplementation("org.springframework.boot:spring-boot-testcontainers")
+ testImplementation("org.testcontainers:postgresql")
compileOnly("org.projectlombok:lombok")
runtimeOnly("org.postgresql:postgresql")
annotationProcessor("org.projectlombok:lombok")
diff --git a/src/main/java/de/szut/store/supplier/Supplier.java b/src/main/java/de/szut/store/supplier/Supplier.java
index 845ab41..9b78e14 100644
--- a/src/main/java/de/szut/store/supplier/Supplier.java
+++ b/src/main/java/de/szut/store/supplier/Supplier.java
@@ -20,7 +20,7 @@ public class Supplier {
@NotBlank
private String name;
- @OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
+ @OneToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
private Contact contact;
@OneToMany(mappedBy = "supplier", fetch = FetchType.EAGER, cascade = CascadeType.ALL)
diff --git a/src/main/java/de/szut/store/supplier/SupplierController.java b/src/main/java/de/szut/store/supplier/SupplierController.java
index 27b3ac1..00715cf 100644
--- a/src/main/java/de/szut/store/supplier/SupplierController.java
+++ b/src/main/java/de/szut/store/supplier/SupplierController.java
@@ -8,10 +8,8 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.validation.ValidationAutoConfiguration;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
-import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
-import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
diff --git a/src/test/java/de/szut/store/IntegrationTest.java b/src/test/java/de/szut/store/IntegrationTest.java
new file mode 100644
index 0000000..c9bf0e2
--- /dev/null
+++ b/src/test/java/de/szut/store/IntegrationTest.java
@@ -0,0 +1,34 @@
+package de.szut.store;
+
+import de.szut.store.article.ArticleRepository;
+import de.szut.store.supplier.SupplierRepository;
+import org.junit.jupiter.api.BeforeEach;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.context.ActiveProfiles;
+
+import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.web.servlet.MockMvc;
+
+@SpringBootTest
+@AutoConfigureMockMvc
+@ActiveProfiles("it")
+@ContextConfiguration(initializers = PostgresContextInitializer.class)
+public abstract class IntegrationTest {
+
+ @Autowired
+ protected MockMvc mockMvc;
+
+ @Autowired
+ protected ArticleRepository articleRepository;
+
+ @Autowired
+ protected SupplierRepository supplierRepository;
+
+ @BeforeEach
+ void setUp() {
+ articleRepository.deleteAll();
+ supplierRepository.deleteAll();
+ }
+}
diff --git a/src/test/java/de/szut/store/PostgresContextInitializer.java b/src/test/java/de/szut/store/PostgresContextInitializer.java
new file mode 100644
index 0000000..41e41ae
--- /dev/null
+++ b/src/test/java/de/szut/store/PostgresContextInitializer.java
@@ -0,0 +1,26 @@
+package de.szut.store;
+
+import org.springframework.boot.test.util.TestPropertyValues;
+import org.springframework.context.ApplicationContextInitializer;
+import org.springframework.context.ConfigurableApplicationContext;
+import org.testcontainers.containers.PostgreSQLContainer;
+import org.testcontainers.utility.DockerImageName;
+
+public class PostgresContextInitializer implements ApplicationContextInitializer {
+
+ private static final PostgreSQLContainer> postgres = new PostgreSQLContainer<>(DockerImageName.parse("postgres:16"))
+ .withDatabaseName("test_db")
+ .withUsername("test-db-user")
+ .withPassword("test-db-password")
+ .withReuse(true);
+
+ public void initialize(ConfigurableApplicationContext configurableApplicationContext) {
+ postgres.start();
+
+ TestPropertyValues.of(
+ "spring.datasource.url=" + postgres.getJdbcUrl(),
+ "spring.datasource.username=" + postgres.getUsername(),
+ "spring.datasource.password=" + postgres.getPassword()
+ ).applyTo(configurableApplicationContext.getEnvironment());
+ }
+}
\ No newline at end of file
diff --git a/src/test/java/de/szut/store/supplier/CreateSupplierTest.java b/src/test/java/de/szut/store/supplier/CreateSupplierTest.java
new file mode 100644
index 0000000..b7b2f6b
--- /dev/null
+++ b/src/test/java/de/szut/store/supplier/CreateSupplierTest.java
@@ -0,0 +1,51 @@
+package de.szut.store.supplier;
+
+import de.szut.store.IntegrationTest;
+import org.json.JSONObject;
+import org.junit.jupiter.api.Test;
+import org.springframework.http.MediaType;
+
+import java.util.Optional;
+
+import static org.hamcrest.Matchers.is;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
+public class CreateSupplierTest extends IntegrationTest {
+
+ @Test
+ void createSupplier() throws Exception {
+ String content = """
+ {
+ "name": "Meier",
+ "street": "Benquestraße 50",
+ "zipcode": "28209",
+ "city": "Bremen",
+ "phone": "01637122020"
+ }
+ """;
+
+ final String contentAsString = this.mockMvc
+ .perform(post("/store/supplier").content(content).contentType(MediaType.APPLICATION_JSON))
+ .andExpect(status().isCreated())
+ .andExpect(jsonPath("name", is("Meier")))
+ .andExpect(jsonPath("street", is("Benquestraße 50")))
+ .andExpect(jsonPath("city", is("Bremen")))
+ .andExpect(jsonPath("zipcode", is("28209")))
+ .andExpect(jsonPath("phone", is("01637122020")))
+ .andReturn()
+ .getResponse()
+ .getContentAsString();
+
+ final Long id = Long.parseLong(new JSONObject(contentAsString).get("id").toString());
+ final Optional result = supplierRepository.findById(id);
+ assertThat(result.isPresent()).isTrue();
+ assertThat(result.get().getName()).isEqualTo("Meier");
+ assertThat(result.get().getContact().getStreet()).isEqualTo("Benquestraße 50");
+ assertThat(result.get().getContact().getZipcode()).isEqualTo("28209");
+ assertThat(result.get().getContact().getCity()).isEqualTo("Bremen");
+ assertThat(result.get().getContact().getPhone()).isEqualTo("01637122020");
+ }
+}
diff --git a/src/test/java/de/szut/store/supplier/FindAllSupplierTest.java b/src/test/java/de/szut/store/supplier/FindAllSupplierTest.java
new file mode 100644
index 0000000..842e7c5
--- /dev/null
+++ b/src/test/java/de/szut/store/supplier/FindAllSupplierTest.java
@@ -0,0 +1,36 @@
+package de.szut.store.supplier;
+
+import de.szut.store.IntegrationTest;
+import de.szut.store.contact.Contact;
+import org.junit.jupiter.api.Test;
+
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.hasSize;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
+
+public class FindAllSupplierTest extends IntegrationTest {
+
+ @Test
+ void findAll() throws Exception {
+ var supplier = new Supplier();
+ supplier.setName("Meier");
+ var contact = new Contact();
+ contact.setStreet("Hauptstraße");
+ contact.setZipcode("12345");
+ contact.setCity("Bremen");
+ contact.setPhone("+4912345");
+ supplier.setContact(contact);
+ this.supplierRepository.save(supplier);
+ final var contentAsString = this.mockMvc
+ .perform(get("/store/supplier"))
+ .andExpect(status().is2xxSuccessful())
+ .andExpect(jsonPath("$", hasSize(1)))
+ .andExpect(jsonPath("$[0].name", is("Meier")))
+ .andExpect(jsonPath("$[0].street", is("Hauptstraße")))
+ .andExpect(jsonPath("$[0].zipcode", is("12345")))
+ .andExpect(jsonPath("$[0].city", is("Bremen")))
+ .andExpect(jsonPath("$[0].phone", is("+4912345")));
+ }
+}
diff --git a/src/test/resources/de/szut/store/application-it.properties b/src/test/resources/de/szut/store/application-it.properties
new file mode 100644
index 0000000..b8de14f
--- /dev/null
+++ b/src/test/resources/de/szut/store/application-it.properties
@@ -0,0 +1,3 @@
+spring.datasource.url=set_by_test_containers
+spring.datasource.username=set_by_test_containers
+spring.datasource.password=set_by_test_containers
\ No newline at end of file