From 282cd67ad4fa8b6744e862528ecb638250fe2afd Mon Sep 17 00:00:00 2001 From: Abhinav Pandey Date: Sat, 2 Jul 2022 16:56:07 +0530 Subject: [PATCH 1/4] BAEL-3201 - Unit testing with Redis test containers --- .../spring-boot-testing-2/pom.xml | 10 +++ .../RedisTestcontainersApplication.java | 13 ++++ .../redistestcontainers/hash/Product.java | 55 ++++++++++++++ .../repository/ProductRepository.java | 9 +++ .../service/ProductService.java | 31 ++++++++ .../ProductServiceIntegrationTest.java | 75 +++++++++++++++++++ 6 files changed, 193 insertions(+) create mode 100644 spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/redistestcontainers/RedisTestcontainersApplication.java create mode 100644 spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/redistestcontainers/hash/Product.java create mode 100644 spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/redistestcontainers/repository/ProductRepository.java create mode 100644 spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/redistestcontainers/service/ProductService.java create mode 100644 spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/redistestcontainers/service/ProductServiceIntegrationTest.java diff --git a/spring-boot-modules/spring-boot-testing-2/pom.xml b/spring-boot-modules/spring-boot-testing-2/pom.xml index 556142b480..e4f3f122af 100644 --- a/spring-boot-modules/spring-boot-testing-2/pom.xml +++ b/spring-boot-modules/spring-boot-testing-2/pom.xml @@ -23,6 +23,10 @@ org.springframework.boot spring-boot-starter-web-services + + org.springframework.boot + spring-boot-starter-data-redis + wsdl4j wsdl4j @@ -38,6 +42,12 @@ 3.1.3 test + + org.testcontainers + testcontainers + 1.17.2 + test + diff --git a/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/redistestcontainers/RedisTestcontainersApplication.java b/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/redistestcontainers/RedisTestcontainersApplication.java new file mode 100644 index 0000000000..50efd56751 --- /dev/null +++ b/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/redistestcontainers/RedisTestcontainersApplication.java @@ -0,0 +1,13 @@ +package com.baeldung.redistestcontainers; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class RedisTestcontainersApplication { + + public static void main(String[] args) { + SpringApplication.run(RedisTestcontainersApplication.class, args); + } + +} diff --git a/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/redistestcontainers/hash/Product.java b/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/redistestcontainers/hash/Product.java new file mode 100644 index 0000000000..3345a17c79 --- /dev/null +++ b/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/redistestcontainers/hash/Product.java @@ -0,0 +1,55 @@ +package com.baeldung.redistestcontainers.hash; + +import org.springframework.data.redis.core.RedisHash; + +import java.io.Serializable; + +@RedisHash("product") +public class Product implements Serializable { + private String id; + private String name; + private double price; + + // Constructor, getters and setters + public Product() { + } + + public Product(String id, String name, double price) { + this.id = id; + this.name = name; + this.price = price; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public double getPrice() { + return price; + } + + public void setPrice(double price) { + this.price = price; + } + + @Override + public String toString() { + return "Product{" + + "id='" + id + '\'' + + ", name='" + name + '\'' + + ", price=" + price + + '}'; + } +} \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/redistestcontainers/repository/ProductRepository.java b/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/redistestcontainers/repository/ProductRepository.java new file mode 100644 index 0000000000..5851c282e0 --- /dev/null +++ b/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/redistestcontainers/repository/ProductRepository.java @@ -0,0 +1,9 @@ +package com.baeldung.redistestcontainers.repository; + +import com.baeldung.redistestcontainers.hash.Product; +import org.springframework.data.repository.CrudRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface ProductRepository extends CrudRepository { +} diff --git a/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/redistestcontainers/service/ProductService.java b/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/redistestcontainers/service/ProductService.java new file mode 100644 index 0000000000..3eb0149ef1 --- /dev/null +++ b/spring-boot-modules/spring-boot-testing-2/src/main/java/com/baeldung/redistestcontainers/service/ProductService.java @@ -0,0 +1,31 @@ +package com.baeldung.redistestcontainers.service; + +import com.baeldung.redistestcontainers.hash.Product; +import com.baeldung.redistestcontainers.repository.ProductRepository; +import org.springframework.stereotype.Service; + +@Service +public class ProductService { + + private final ProductRepository productRepository; + + public ProductService(ProductRepository productRepository) { + this.productRepository = productRepository; + } + + public Product getProduct(String id) { + return productRepository.findById(id).orElse(null); + } + + void createProduct(Product product) { + productRepository.save(product); + } + + void updateProduct(Product product) { + productRepository.save(product); + } + + void deleteProduct(String id) { + productRepository.deleteById(id); + } +} \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/redistestcontainers/service/ProductServiceIntegrationTest.java b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/redistestcontainers/service/ProductServiceIntegrationTest.java new file mode 100644 index 0000000000..55ff2b8676 --- /dev/null +++ b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/redistestcontainers/service/ProductServiceIntegrationTest.java @@ -0,0 +1,75 @@ +package com.baeldung.redistestcontainers.service; + +import com.baeldung.redistestcontainers.hash.Product; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.testcontainers.containers.GenericContainer; +import org.testcontainers.utility.DockerImageName; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; + +@SpringBootTest +public class ProductServiceIntegrationTest { + + static { + GenericContainer redis = new GenericContainer<>(DockerImageName.parse("redis:5.0.3-alpine")) + .withExposedPorts(6379); + redis.start(); + System.setProperty("spring.redis.host", redis.getHost()); + System.setProperty("spring.redis.port", redis.getMappedPort(6379).toString()); + } + + @Autowired + private ProductService productService; + + @Test + void testCreateProduct() { + Product product = new Product("1", "Test Product", 10.0); + productService.createProduct(product); + Product productFromDb = productService.getProduct("1"); + assertEquals("1", productFromDb.getId()); + assertEquals("Test Product", productFromDb.getName()); + assertEquals(10.0, productFromDb.getPrice()); + } + + @Test + void testUpdateProduct() { + Product product = new Product("1", "Test Product", 10.0); + productService.createProduct(product); + Product productFromDb = productService.getProduct("1"); + assertEquals("1", productFromDb.getId()); + assertEquals("Test Product", productFromDb.getName()); + assertEquals(10.0, productFromDb.getPrice()); + productFromDb.setName("Updated Product"); + productFromDb.setPrice(20.0); + productService.updateProduct(productFromDb); + Product updatedProductFromDb = productService.getProduct("1"); + assertEquals("Updated Product", updatedProductFromDb.getName()); + assertEquals(20.0, updatedProductFromDb.getPrice()); + } + + @Test + void testDeleteProduct() { + Product product = new Product("1", "Test Product", 10.0); + productService.createProduct(product); + Product productFromDb = productService.getProduct("1"); + assertEquals("1", productFromDb.getId()); + assertEquals("Test Product", productFromDb.getName()); + assertEquals(10.0, productFromDb.getPrice()); + productService.deleteProduct("1"); + Product deletedProductFromDb = productService.getProduct("1"); + assertNull(deletedProductFromDb); + } + + @Test + void testGetProduct() { + Product product = new Product("1", "Test Product", 10.0); + productService.createProduct(product); + Product productFromDb = productService.getProduct("1"); + assertEquals("1", productFromDb.getId()); + assertEquals("Test Product", productFromDb.getName()); + assertEquals(10.0, productFromDb.getPrice()); + } +} \ No newline at end of file From bc4857f6be7142ca7855efce6bbc77700fe4ecf0 Mon Sep 17 00:00:00 2001 From: Abhinav Pandey Date: Sun, 10 Jul 2022 19:14:31 +0530 Subject: [PATCH 2/4] BAEL-3201 - Updated test method names --- .../service/ProductServiceIntegrationTest.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/redistestcontainers/service/ProductServiceIntegrationTest.java b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/redistestcontainers/service/ProductServiceIntegrationTest.java index 55ff2b8676..519db1b335 100644 --- a/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/redistestcontainers/service/ProductServiceIntegrationTest.java +++ b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/redistestcontainers/service/ProductServiceIntegrationTest.java @@ -15,7 +15,7 @@ public class ProductServiceIntegrationTest { static { GenericContainer redis = new GenericContainer<>(DockerImageName.parse("redis:5.0.3-alpine")) - .withExposedPorts(6379); + .withExposedPorts(6379); redis.start(); System.setProperty("spring.redis.host", redis.getHost()); System.setProperty("spring.redis.port", redis.getMappedPort(6379).toString()); @@ -25,7 +25,7 @@ public class ProductServiceIntegrationTest { private ProductService productService; @Test - void testCreateProduct() { + void givenProductCreated_whenGettingProductById_thenProductExistsAndHasSameProperties() { Product product = new Product("1", "Test Product", 10.0); productService.createProduct(product); Product productFromDb = productService.getProduct("1"); @@ -35,7 +35,7 @@ public class ProductServiceIntegrationTest { } @Test - void testUpdateProduct() { + void givenProductCreatedAndUpdated_whenGettingTheProduct_thenUpdatedProductReturned() { Product product = new Product("1", "Test Product", 10.0); productService.createProduct(product); Product productFromDb = productService.getProduct("1"); @@ -51,7 +51,7 @@ public class ProductServiceIntegrationTest { } @Test - void testDeleteProduct() { + void givenProductCreatedAndDeleted_whenGettingTheProduct_thenNoProductReturned() { Product product = new Product("1", "Test Product", 10.0); productService.createProduct(product); Product productFromDb = productService.getProduct("1"); @@ -64,7 +64,7 @@ public class ProductServiceIntegrationTest { } @Test - void testGetProduct() { + void givenProductCreated_whenGettingProductById_thenSameProductReturned() { Product product = new Product("1", "Test Product", 10.0); productService.createProduct(product); Product productFromDb = productService.getProduct("1"); From 0518e6726b2817a5dc302e4ae545034e47919ea7 Mon Sep 17 00:00:00 2001 From: Abhinav Pandey Date: Sat, 16 Jul 2022 20:18:52 +0530 Subject: [PATCH 3/4] BAEL-3201 - Skipping test container based test --- ...ceIntegrationTest.java => ProductServiceManualTest.java} | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) rename spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/redistestcontainers/service/{ProductServiceIntegrationTest.java => ProductServiceManualTest.java} (95%) diff --git a/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/redistestcontainers/service/ProductServiceIntegrationTest.java b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/redistestcontainers/service/ProductServiceManualTest.java similarity index 95% rename from spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/redistestcontainers/service/ProductServiceIntegrationTest.java rename to spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/redistestcontainers/service/ProductServiceManualTest.java index 519db1b335..00c0c3a1f7 100644 --- a/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/redistestcontainers/service/ProductServiceIntegrationTest.java +++ b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/redistestcontainers/service/ProductServiceManualTest.java @@ -10,8 +10,12 @@ import org.testcontainers.utility.DockerImageName; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNull; +/** + * Requires Docker running on the machine to run without errors + * Therefore, skipped from pipeline + */ @SpringBootTest -public class ProductServiceIntegrationTest { +public class ProductServiceManualTest { static { GenericContainer redis = new GenericContainer<>(DockerImageName.parse("redis:5.0.3-alpine")) From bf5ed18f63eac52bcf15613aa4d1a128656239b5 Mon Sep 17 00:00:00 2001 From: Abhinav Pandey Date: Mon, 18 Jul 2022 14:35:30 +0000 Subject: [PATCH 4/4] BAEL-3201 - Deleting Integration Test file --- .../ProductServiceIntegrationTest.java | 75 ------------------- 1 file changed, 75 deletions(-) delete mode 100644 spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/redistestcontainers/service/ProductServiceIntegrationTest.java diff --git a/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/redistestcontainers/service/ProductServiceIntegrationTest.java b/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/redistestcontainers/service/ProductServiceIntegrationTest.java deleted file mode 100644 index 519db1b335..0000000000 --- a/spring-boot-modules/spring-boot-testing-2/src/test/java/com/baeldung/redistestcontainers/service/ProductServiceIntegrationTest.java +++ /dev/null @@ -1,75 +0,0 @@ -package com.baeldung.redistestcontainers.service; - -import com.baeldung.redistestcontainers.hash.Product; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.testcontainers.containers.GenericContainer; -import org.testcontainers.utility.DockerImageName; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNull; - -@SpringBootTest -public class ProductServiceIntegrationTest { - - static { - GenericContainer redis = new GenericContainer<>(DockerImageName.parse("redis:5.0.3-alpine")) - .withExposedPorts(6379); - redis.start(); - System.setProperty("spring.redis.host", redis.getHost()); - System.setProperty("spring.redis.port", redis.getMappedPort(6379).toString()); - } - - @Autowired - private ProductService productService; - - @Test - void givenProductCreated_whenGettingProductById_thenProductExistsAndHasSameProperties() { - Product product = new Product("1", "Test Product", 10.0); - productService.createProduct(product); - Product productFromDb = productService.getProduct("1"); - assertEquals("1", productFromDb.getId()); - assertEquals("Test Product", productFromDb.getName()); - assertEquals(10.0, productFromDb.getPrice()); - } - - @Test - void givenProductCreatedAndUpdated_whenGettingTheProduct_thenUpdatedProductReturned() { - Product product = new Product("1", "Test Product", 10.0); - productService.createProduct(product); - Product productFromDb = productService.getProduct("1"); - assertEquals("1", productFromDb.getId()); - assertEquals("Test Product", productFromDb.getName()); - assertEquals(10.0, productFromDb.getPrice()); - productFromDb.setName("Updated Product"); - productFromDb.setPrice(20.0); - productService.updateProduct(productFromDb); - Product updatedProductFromDb = productService.getProduct("1"); - assertEquals("Updated Product", updatedProductFromDb.getName()); - assertEquals(20.0, updatedProductFromDb.getPrice()); - } - - @Test - void givenProductCreatedAndDeleted_whenGettingTheProduct_thenNoProductReturned() { - Product product = new Product("1", "Test Product", 10.0); - productService.createProduct(product); - Product productFromDb = productService.getProduct("1"); - assertEquals("1", productFromDb.getId()); - assertEquals("Test Product", productFromDb.getName()); - assertEquals(10.0, productFromDb.getPrice()); - productService.deleteProduct("1"); - Product deletedProductFromDb = productService.getProduct("1"); - assertNull(deletedProductFromDb); - } - - @Test - void givenProductCreated_whenGettingProductById_thenSameProductReturned() { - Product product = new Product("1", "Test Product", 10.0); - productService.createProduct(product); - Product productFromDb = productService.getProduct("1"); - assertEquals("1", productFromDb.getId()); - assertEquals("Test Product", productFromDb.getName()); - assertEquals(10.0, productFromDb.getPrice()); - } -} \ No newline at end of file