Obsługa usługi Spring Cloud Azure dla Testcontainers

W tym artykule opisano sposób integrowania platformy Spring Cloud azure z usługą Testcontainers w celu pisania skutecznych testów integracji dla aplikacji.

Testcontainer to platforma typu open source służąca do zapewniania wyrzuconych, lekkich wystąpień baz danych, brokerów komunikatów, przeglądarek internetowych lub niemal wszystkich elementów, które mogą być uruchamiane w kontenerze platformy Docker. Integruje się z programem JUnit, umożliwiając pisanie klasy testowej, która może uruchomić kontener przed uruchomieniem któregokolwiek z testów. Narzędzie Testcontainer jest szczególnie przydatne podczas pisania testów integracji, które komunikują się z prawdziwą usługą zaplecza.

Biblioteka spring-cloud-azure-testcontainers obsługuje teraz testowanie integracji dla następujących usług platformy Azure:

Połączenia usług

Połączenie usługi to połączenie z dowolną usługą zdalną. Mechanizm automatycznej konfiguracji w Spring Boot może wykorzystywać informacje o połączeniu z usługą i używać ich do nawiązania połączenia ze zdalną usługą. W tym przypadku szczegóły połączenia mają pierwszeństwo przed wszelkimi właściwościami konfiguracji powiązanymi z połączeniem.

Gdy używasz narzędzia Testcontainers, możesz automatycznie utworzyć szczegóły połączenia dla usługi uruchomionej w kontenerze, dodając adnotacje do pola kontenera w klasie testowej.

xxxContainerConnectionDetailsFactory klasy są rejestrowane za pomocą spring.factories. Te fabryki tworzą fasolę ConnectionDetails na podstawie określonej podklasy Container lub nazwy obrazu platformy Docker.

Poniższa tabela zawiera informacje o klasach fabryk szczegółów połączenia obsługiwanych przez plik JAR spring-cloud-azure-testcontainers:

Klasa fabryczna szczegółów połączenia Bean szczegółów połączenia
CosmosContainerConnectionDetailsFactory AzureCosmosConnectionDetails
StorageBlobContainerConnectionDetailsFactory AzureStorageBlobConnectionDetails
StorageQueueContainerConnectionDetailsFactory AzureStorageQueueConnectionDetails
EventHubsContainerConnectionDetailsFactory AzureEventHubsConnectionDetails
ServiceBusContainerConnectionDetailsFactory AzureServiceBusConnectionDetails

Konfigurowanie zależności

Następująca konfiguracja konfiguruje wymagane zależności:

  <properties>
    <version.spring.cloud.azure>7.4.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>

Korzystanie z usługi Testcontainers

W poniższym przykładzie kodu pokazano podstawowe użycie elementów 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);
    }

}

Aby użyć CosmosDBEmulatorContainer, musisz przygotować KeyStore dla TLS/SSL. Aby uzyskać więcej informacji, zobacz Moduł platformy Azure usługi Cosmos DB w dokumentacji narzędzia Testcontainers. Dzięki @ServiceConnection ta konfiguracja umożliwia komponentom bean związanym z usługą Cosmos DB w aplikacji komunikację z usługą Cosmos DB działającą w kontenerze Docker zarządzanym przez Testcontainers. Ta konfiguracja automatycznie definiuje bean AzureCosmosConnectionDetails, którego autokonfiguracja Cosmos DB następnie używa do zastąpienia wszelkich właściwości konfiguracyjnych związanych z połączeniem.

Próbki

Aby uzyskać więcej informacji, zobacz spring-cloud-azure-testcontainers przykłady.