Condividi tramite


Supporto di Spring Cloud Azure per Testcontainers

Questo articolo descrive come integrare Spring Cloud Azure con Testcontainers per scrivere test di integrazione efficaci per le applicazioni.

Testcontainer è un framework open source per fornire istanze throwaway, leggere di database, broker di messaggi, Web browser o semplicemente tutto ciò che può essere eseguito in un contenitore Docker. Si integra con JUnit, consentendo di scrivere una classe di test in grado di avviare un contenitore prima dell'esecuzione di uno dei test. Testcontainer è particolarmente utile per la scrittura di test di integrazione che comunicano con un servizio back-end reale.

La libreria spring-cloud-azure-testcontainers supporta ora i test di integrazione per i servizi di Azure seguenti:

Connessioni al servizio

Una connessione al servizio è una connessione a qualsiasi servizio remoto. La configurazione automatica di Spring Boot può utilizzare i dettagli di una connessione al servizio e usarli per stabilire una connessione a un servizio remoto. In questo caso, i dettagli della connessione hanno la precedenza su qualsiasi proprietà di configurazione correlata alla connessione.

Quando si usano Testcontainers, è possibile creare automaticamente i dettagli di connessione per un servizio in esecuzione in un contenitore annotando il campo contenitore nella classe di test.

xxxContainerConnectionDetailsFactory le classi vengono registrate con spring.factories. Queste factory creano un ConnectionDetails bean in base a una sottoclasse Container specifica o al nome dell'immagine Docker.

Nella tabella seguente vengono fornite informazioni sulle classi factory dei dettagli della connessione supportate nel file JAR spring-cloud-azure-testcontainers:

Classe factory dei dettagli della connessione Bean dei dettagli della connessione
CosmosContainerConnectionDetailsFactory AzureCosmosConnectionDetails
StorageBlobContainerConnectionDetailsFactory AzureStorageBlobConnectionDetails
StorageQueueContainerConnectionDetailsFactory AzureStorageQueueConnectionDetails
EventHubsContainerConnectionDetailsFactory AzureEventHubsConnectionDetails
ServiceBusContainerConnectionDetailsFactory AzureServiceBusConnectionDetails

Configurare le dipendenze

La configurazione seguente configura le dipendenze necessarie:

  <properties>
    <version.spring.cloud.azure>7.1.0</version.spring.cloud.azure>
  </properties>

  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>com.azure.spring</groupId>
        <artifactId>spring-cloud-azure-dependencies</artifactId>
        <version>${version.spring.cloud.azure}</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
    </dependencies>
  </dependencyManagement>

  <dependencies>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-test</artifactId>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.testcontainers</groupId>
      <artifactId>testcontainers-junit-jupiter</artifactId>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>com.azure.spring</groupId>
      <artifactId>spring-cloud-azure-testcontainers</artifactId>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>com.azure.spring</groupId>
      <artifactId>spring-cloud-azure-starter-cosmos</artifactId>
      <scope>test</scope>
    </dependency>
  </dependencies>

Usare Testcontainers

L'esempio di codice seguente illustra l'utilizzo di base di Testcontainers:

@SpringBootTest(classes = CosmosTestcontainersTest.class)
@Testcontainers
@ExtendWith(SpringExtension.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"))
                .waitingFor(Wait.forHttps("/_explorer/emulator.pem").forStatusCode(200).allowInsecure())
                .withStartupTimeout(Duration.ofMinutes(3));

    @BeforeAll
    public static void setup() throws IOException, CertificateException, KeyStoreException, NoSuchAlgorithmException {
        Path keyStoreFile = new File(tempFolder, "azure-cosmos-emulator.keystore").toPath();
        KeyStore keyStore = cosmos.buildNewKeyStore();
        try (var out = Files.newOutputStream(keyStoreFile.toFile().toPath())) {
            keyStore.store(out, cosmos.getEmulatorKey().toCharArray());
        }

        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);
    }

}

Per usare CosmosDBEmulatorContainer, è necessario preparare un KeyStore per TLS/SSL. Per altre informazioni, vedere modulo di Azure di Cosmos DB nella documentazione di Testcontainers. Con @ServiceConnection, questa configurazione consente ai fagioli correlati a Cosmos DB nell'app di comunicare con Cosmos DB in esecuzione all'interno del contenitore Docker gestito da Testcontainers. Questa configurazione definisce automaticamente un AzureCosmosConnectionDetails bean, che la configurazione automatica di Cosmos DB usa per eseguire l'override di tutte le proprietà di configurazione correlate alla connessione.

Campioni

Per altre informazioni, vedere gli esempi spring-cloud-azure-testcontainers.