diff --git a/README.md b/README.md
index 7869986a0..de1e5fc06 100644
--- a/README.md
+++ b/README.md
@@ -108,6 +108,14 @@
|---------------------------------------------------------------------------------------------------------------------|--------------------------------|--------------------------------|
| [spring-petclinic-microservices](spring-petclinic-microservices) | ✅ | ❌ |
+### TestContainers Support
+
+| Sample Project | Support Spring Cloud Azure 4.x | Support Spring Cloud Azure 5.x |
+|------------------------------------------------------------------|--------------------------------|--------------------------------|
+| [testContainers for Cosmos](testcontainers/cosmos) | ❌ | ✅ |
+| [testContainers for Storage Blob](testcontainers/storage-blob) | ❌ | ✅ |
+| [testContainers for Storage Queue](testcontainers/storage-queue) | ❌ | ✅ |
+
## Getting Help
- If you have any question about using these samples, please [create an new issue](https://github.com/Azure-Samples/azure-spring-boot-samples/issues/new/choose).
diff --git a/pom.xml b/pom.xml
index 102b82392..180eb8e9f 100644
--- a/pom.xml
+++ b/pom.xml
@@ -195,6 +195,9 @@
storage/spring-cloud-azure-starter-integration-storage-queue/storage-queue-integration
storage/spring-cloud-azure-starter-storage-queue/storage-queue-client
storage/spring-messaging-azure-storage-queue/storage-queue-spring-messaging
+ testcontainers/cosmos
+ testcontainers/storage-blob
+ testcontainers/storage-queue
true
@@ -208,7 +211,7 @@
5.15.0
3.1.1.RELEASE
3.1.0
-
+ 1.20.0
2.22.0
4.11.0
@@ -224,6 +227,11 @@
jakarta.persistence-api
${version.jakarta-persistence}
+
+ org.testcontainers
+ azure
+ ${version.testcontainers.azure}
+
diff --git a/testcontainers/README.md b/testcontainers/README.md
new file mode 100644
index 000000000..e756b544c
--- /dev/null
+++ b/testcontainers/README.md
@@ -0,0 +1,43 @@
+---
+page_type: sample
+languages:
+- java
+products:
+- spring-cloud-azure-testcontainers
+name: Spring Cloud Azure Testcontainers samples
+description: These samples demonstrates how to use Spring Cloud Azure Testcontainers in test cases.
+---
+
+# Testcontainers Service Connection Samples for Spring Cloud Azure
+Testcontainers is an open source framework for providing throwaway, lightweight instances of databases, message brokers, web browsers, or just about anything that can run in a Docker container.
+
+We provide `spring-cloud-azure-testcontainers` library to support Testcontainers in Spring Cloud Azure. It allows you to write a test class that can start up a container before any of the tests run. Testcontainers is especially useful for writing integration tests that talk to a real backend service.
+
+This sample project demonstrates how to use Testcontainers Service Connection with Azure Cosmos DB, Azure Storage Blob, and Azure Storage Queue in test cases.
+
+## What You Need
+
+- [Docker environment](https://java.testcontainers.org/supported_docker_environment/)
+- [JDK8](https://www.oracle.com/java/technologies/downloads/) or later
+- Maven
+- You can also import the code straight into your IDE:
+ - [IntelliJ IDEA](https://www.jetbrains.com/idea/download)
+
+## Run Locally
+With docker environment running, you can directly run the tests.
+
+### Run the sample with Maven
+
+In your terminal, run `mvn clean test`.
+
+```shell
+mvn clean test
+```
+
+### Run the sample in IDEs
+
+You can debug your sample by IDEs.
+
+* If your tool is `IDEA`, please refer to [Debug your first Java application](https://www.jetbrains.com/help/idea/debugging-your-first-java-application.html) and [add environment variables](https://www.jetbrains.com/help/objc/add-environment-variables-and-program-arguments.html#add-environment-variables).
+
+* If your tool is `ECLIPSE`, please refer to [Debugging the Eclipse IDE for Java Developers](https://www.eclipse.org/community/eclipse_newsletter/2017/june/article1.php) and [Eclipse Environment Variable Setup](https://examples.javacodegeeks.com/desktop-java/ide/eclipse/eclipse-environment-variable-setup-example).
diff --git a/testcontainers/cosmos/pom.xml b/testcontainers/cosmos/pom.xml
new file mode 100644
index 000000000..de69c606e
--- /dev/null
+++ b/testcontainers/cosmos/pom.xml
@@ -0,0 +1,68 @@
+
+
+ 4.0.0
+
+
+ com.azure.spring
+ azure-spring-boot-samples
+ 1.0.0
+ ../../pom.xml
+
+
+ spring-cloud-azure-testcontainers-for-cosmos-sample
+ 1.0.0
+ jar
+
+ TestContainers for Azure Cosmos DB
+
+
+
+ com.azure.spring
+ spring-cloud-azure-starter-cosmos
+ test
+
+
+ com.azure.spring
+ spring-cloud-azure-testcontainers
+ test
+
+
+ org.testcontainers
+ junit-jupiter
+ test
+
+
+ org.testcontainers
+ azure
+ test
+
+
+ org.springframework.boot
+ spring-boot-test
+ test
+
+
+ org.junit.jupiter
+ junit-jupiter-api
+ test
+
+
+ org.assertj
+ assertj-core
+ test
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+ true
+
+
+
+
+
diff --git a/testcontainers/cosmos/src/test/java/CosmosTestcontainersTest.java b/testcontainers/cosmos/src/test/java/CosmosTestcontainersTest.java
new file mode 100644
index 000000000..e36e96ead
--- /dev/null
+++ b/testcontainers/cosmos/src/test/java/CosmosTestcontainersTest.java
@@ -0,0 +1,72 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+import com.azure.cosmos.CosmosClient;
+import com.azure.cosmos.models.CosmosContainerResponse;
+import com.azure.cosmos.models.CosmosDatabaseResponse;
+import com.azure.spring.cloud.autoconfigure.implementation.context.AzureGlobalPropertiesAutoConfiguration;
+import com.azure.spring.cloud.autoconfigure.implementation.cosmos.AzureCosmosAutoConfiguration;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.jupiter.api.io.TempDir;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.testcontainers.containers.CosmosDBEmulatorContainer;
+import org.testcontainers.junit.jupiter.Container;
+import org.testcontainers.junit.jupiter.Testcontainers;
+import org.testcontainers.utility.DockerImageName;
+
+import java.io.File;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.security.KeyStore;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+@SpringBootTest(classes = CosmosTestcontainersTest.class)
+@Testcontainers
+@RunWith(SpringRunner.class)
+@ImportAutoConfiguration(classes = { AzureGlobalPropertiesAutoConfiguration.class, AzureCosmosAutoConfiguration.class})
+public class CosmosTestcontainersTest {
+
+ @TempDir
+ private static File tempFolder;
+
+ @Autowired
+ private CosmosClient client;
+
+ @Container
+ @ServiceConnection
+ static CosmosDBEmulatorContainer cosmos = new CosmosDBEmulatorContainer(
+ DockerImageName.parse("mcr.microsoft.com/cosmosdb/linux/azure-cosmos-emulator:latest"));
+
+ @BeforeClass
+ public static void setup() {
+ cosmos.start();
+ Path keyStoreFile = new File(tempFolder, "azure-cosmos-emulator.keystore").toPath();
+ KeyStore keyStore = cosmos.buildNewKeyStore();
+ try {
+ keyStore.store(Files.newOutputStream(keyStoreFile.toFile().toPath()), cosmos.getEmulatorKey().toCharArray());
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+
+ System.setProperty("javax.net.ssl.trustStore", keyStoreFile.toString());
+ System.setProperty("javax.net.ssl.trustStorePassword", cosmos.getEmulatorKey());
+ System.setProperty("javax.net.ssl.trustStoreType", "PKCS12");
+ }
+
+ @Test
+ public void test() {
+ CosmosDatabaseResponse databaseResponse = client.createDatabaseIfNotExists("Azure");
+ assertThat(databaseResponse.getStatusCode()).isEqualTo(201);
+ CosmosContainerResponse containerResponse = client
+ .getDatabase("Azure")
+ .createContainerIfNotExists("ServiceContainer", "/name");
+ assertThat(containerResponse.getStatusCode()).isEqualTo(201);
+ }
+
+}
diff --git a/testcontainers/storage-blob/pom.xml b/testcontainers/storage-blob/pom.xml
new file mode 100644
index 000000000..d3a9bf0f4
--- /dev/null
+++ b/testcontainers/storage-blob/pom.xml
@@ -0,0 +1,59 @@
+
+
+ 4.0.0
+
+
+ com.azure.spring
+ azure-spring-boot-samples
+ 1.0.0
+ ../../pom.xml
+
+
+ spring-cloud-azure-testcontainers-for-storage-blob-sample
+ 1.0.0
+ jar
+
+ TestContainers for Azure Storage Blob
+
+
+
+ com.azure.spring
+ spring-cloud-azure-starter-storage-blob
+ test
+
+
+ com.azure.spring
+ spring-cloud-azure-testcontainers
+ test
+
+
+ org.springframework.boot
+ spring-boot-test
+ test
+
+
+ org.assertj
+ assertj-core
+ test
+
+
+ org.testcontainers
+ junit-jupiter
+ test
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+ true
+
+
+
+
+
diff --git a/testcontainers/storage-blob/src/test/java/StorageBlobTestcontainersTest.java b/testcontainers/storage-blob/src/test/java/StorageBlobTestcontainersTest.java
new file mode 100644
index 000000000..7f2bd1ae8
--- /dev/null
+++ b/testcontainers/storage-blob/src/test/java/StorageBlobTestcontainersTest.java
@@ -0,0 +1,56 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+import com.azure.spring.cloud.autoconfigure.implementation.context.AzureGlobalPropertiesAutoConfiguration;
+import com.azure.spring.cloud.autoconfigure.implementation.storage.blob.AzureStorageBlobAutoConfiguration;
+import com.azure.spring.cloud.autoconfigure.implementation.storage.blob.AzureStorageBlobResourceAutoConfiguration;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
+import org.springframework.core.io.Resource;
+import org.springframework.core.io.WritableResource;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.util.StreamUtils;
+import org.testcontainers.containers.GenericContainer;
+import org.testcontainers.junit.jupiter.Container;
+import org.testcontainers.junit.jupiter.Testcontainers;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.nio.charset.Charset;
+import static org.assertj.core.api.Assertions.assertThat;
+
+@SpringBootTest(classes = StorageBlobTestcontainersTest.class)
+@Testcontainers
+@RunWith(SpringRunner.class)
+@ImportAutoConfiguration(classes = { AzureGlobalPropertiesAutoConfiguration.class, AzureStorageBlobAutoConfiguration.class, AzureStorageBlobResourceAutoConfiguration.class})
+public class StorageBlobTestcontainersTest {
+ @Container
+ @ServiceConnection
+ private static final GenericContainer> AZURITE_CONTAINER = new GenericContainer<>(
+ "mcr.microsoft.com/azure-storage/azurite:latest")
+ .withExposedPorts(10000);
+
+ @Value("azure-blob://testcontainers/message.txt")
+ private Resource blobFile;
+
+ @BeforeClass
+ public static void setup() {
+ AZURITE_CONTAINER.start();
+ }
+
+ @Test
+ public void test() throws IOException {
+ String originalContent = "Hello World!";
+ try (OutputStream os = ((WritableResource) this.blobFile).getOutputStream()) {
+ os.write(originalContent.getBytes());
+ }
+ String resultContent = StreamUtils.copyToString(this.blobFile.getInputStream(), Charset.defaultCharset());
+ assertThat(resultContent).isEqualTo(originalContent);
+ }
+
+}
diff --git a/testcontainers/storage-queue/pom.xml b/testcontainers/storage-queue/pom.xml
new file mode 100644
index 000000000..b28988ade
--- /dev/null
+++ b/testcontainers/storage-queue/pom.xml
@@ -0,0 +1,58 @@
+
+
+ 4.0.0
+
+
+ com.azure.spring
+ azure-spring-boot-samples
+ 1.0.0
+ ../../pom.xml
+
+
+ spring-cloud-azure-testcontainers-for-storage-queue-sample
+ 1.0.0
+ jar
+ TestContainers for Storage Queue
+
+
+
+ com.azure.spring
+ spring-cloud-azure-starter-storage-queue
+ test
+
+
+ com.azure.spring
+ spring-cloud-azure-testcontainers
+ test
+
+
+ org.testcontainers
+ junit-jupiter
+ test
+
+
+ org.springframework.boot
+ spring-boot-test
+ test
+
+
+ org.assertj
+ assertj-core
+ test
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+ true
+
+
+
+
+
diff --git a/testcontainers/storage-queue/src/test/java/StorageQueueTestcontainersTest.java b/testcontainers/storage-queue/src/test/java/StorageQueueTestcontainersTest.java
new file mode 100644
index 000000000..48f8faab7
--- /dev/null
+++ b/testcontainers/storage-queue/src/test/java/StorageQueueTestcontainersTest.java
@@ -0,0 +1,52 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+import com.azure.spring.cloud.autoconfigure.implementation.context.AzureGlobalPropertiesAutoConfiguration;
+import com.azure.spring.cloud.autoconfigure.implementation.storage.queue.AzureStorageQueueAutoConfiguration;
+import com.azure.storage.queue.QueueClient;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
+
+import org.springframework.test.context.TestPropertySource;
+
+import org.springframework.test.context.junit4.SpringRunner;
+import org.testcontainers.containers.GenericContainer;
+import org.testcontainers.junit.jupiter.Container;
+import org.testcontainers.junit.jupiter.Testcontainers;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+@SpringBootTest(classes = StorageQueueTestcontainersTest.class)
+@Testcontainers
+@TestPropertySource(properties = "spring.cloud.azure.storage.queue.queue-name=devstoreaccount1/tc-queue")
+@RunWith(SpringRunner.class)
+@ImportAutoConfiguration(classes = { AzureGlobalPropertiesAutoConfiguration.class, AzureStorageQueueAutoConfiguration.class})
+public class StorageQueueTestcontainersTest {
+
+ @Container
+ @ServiceConnection
+ private static final GenericContainer> AZURITE_CONTAINER = new GenericContainer<>(
+ "mcr.microsoft.com/azure-storage/azurite:latest")
+ .withExposedPorts(10001);
+
+ @Autowired
+ private QueueClient queueClient;
+
+ @BeforeClass
+ public static void setup() {
+ AZURITE_CONTAINER.start();
+ }
+
+ @Test
+ public void test() {
+ String message = "Hello World!";
+ this.queueClient.create();
+ this.queueClient.sendMessage(message);
+ assertThat(this.queueClient.receiveMessage().getBody().toString()).isEqualTo(message);
+ }
+
+}