Wählen Sie Ihre Cookie-Einstellungen aus

Wir verwenden essentielle Cookies und ähnliche Tools, die für die Bereitstellung unserer Website und Services erforderlich sind. Wir verwenden Performance-Cookies, um anonyme Statistiken zu sammeln, damit wir verstehen können, wie Kunden unsere Website nutzen, und Verbesserungen vornehmen können. Essentielle Cookies können nicht deaktiviert werden, aber Sie können auf „Anpassen“ oder „Ablehnen“ klicken, um Performance-Cookies abzulehnen.

Wenn Sie damit einverstanden sind, verwenden AWS und zugelassene Drittanbieter auch Cookies, um nützliche Features der Website bereitzustellen, Ihre Präferenzen zu speichern und relevante Inhalte, einschließlich relevanter Werbung, anzuzeigen. Um alle nicht notwendigen Cookies zu akzeptieren oder abzulehnen, klicken Sie auf „Akzeptieren“ oder „Ablehnen“. Um detailliertere Entscheidungen zu treffen, klicken Sie auf „Anpassen“.

Komponententests

Fokusmodus
Komponententests - AWS SDK for Rust

Die vorliegende Übersetzung wurde maschinell erstellt. Im Falle eines Konflikts oder eines Widerspruchs zwischen dieser übersetzten Fassung und der englischen Fassung (einschließlich infolge von Verzögerungen bei der Übersetzung) ist die englische Fassung maßgeblich.

Die vorliegende Übersetzung wurde maschinell erstellt. Im Falle eines Konflikts oder eines Widerspruchs zwischen dieser übersetzten Fassung und der englischen Fassung (einschließlich infolge von Verzögerungen bei der Übersetzung) ist die englische Fassung maßgeblich.

Es gibt zwar viele Möglichkeiten, Unit-Tests in Ihrem AWS SDK for Rust Projekt zu implementieren, aber es gibt einige, die wir empfehlen:

  • Verwenden Sie es automock aus der mockall Kiste, um Ihre Tests zu erstellen und auszuführen.

  • Verwenden Sie die AWS Smithy-Laufzeitumgebung StaticReplayClient, um einen gefälschten HTTP-Client zu erstellen, der anstelle des Standard-HTTP-Clients verwendet werden kann, der normalerweise von verwendet wird. AWS-Services Dieser Client gibt die von Ihnen angegebenen HTTP-Antworten zurück, anstatt mit dem Dienst über das Netzwerk zu kommunizieren, sodass Tests bekannte Daten für Testzwecke abrufen.

Generieren Sie automatisch Mocks mithilfe von Mockall

Sie können die meisten Mock-Implementierungen, die Ihre Tests benötigen, automatisch generieren, indem Sie die beliebte automock Version aus der Kiste verwenden. mockall

In diesem Beispiel wird eine benutzerdefinierte Methode namens getestet. determine_prefix_file_size() Diese Methode ruft eine benutzerdefinierte list_objects() Wrapper-Methode auf, die Amazon S3 aufruft. Durch Spott kann die determine_prefix_file_size() Methode getestet werdenlist_objects(), ohne Amazon S3 tatsächlich zu kontaktieren.

  1. Fügen Sie in einer Befehlszeile für Ihr Projektverzeichnis die mockall Kiste als Abhängigkeit hinzu:

    $ cargo add mockall

    Dadurch wird die Kiste dem [dependencies] Abschnitt Ihrer Cargo.toml Datei hinzugefügt.

  2. Fügen Sie das automock Modul aus der mockall Kiste hinzu.

    Schließen Sie auch alle anderen Bibliotheken ein AWS-Service , die sich auf das beziehen, das Sie testen, in diesem Fall Amazon S3.

    use aws_sdk_s3 as s3; #[allow(unused_imports)] use mockall::automock; use s3::operation::list_objects_v2::{ListObjectsV2Error, ListObjectsV2Output};
  3. Fügen Sie als Nächstes Code hinzu, der bestimmt, welche von zwei Implementierungen der Amazon S3 S3-Wrapper-Struktur der Anwendung verwendet werden soll.

    • Der echte, der für den Zugriff auf Amazon S3 über das Netzwerk geschrieben wurde.

    • Die Scheinimplementierung, generiert vonmockall.

    In diesem Beispiel erhält die ausgewählte Datei den NamenS3. Die Auswahl ist abhängig von dem test Attribut:

    #[cfg(test)] pub use MockS3Impl as S3; #[cfg(not(test))] pub use S3Impl as S3;
  4. Die S3Impl Struktur ist die Implementierung der Amazon S3 S3-Wrapper-Struktur, an die tatsächlich Anfragen gesendet AWS werden.

    • Wenn das Testen aktiviert ist, wird dieser Code nicht verwendet, da die Anfrage an den Mock gesendet wird und nicht AWS. Das dead_code Attribut weist den Linter an, kein Problem zu melden, wenn der S3Impl Typ nicht verwendet wird.

    • Die Bedingung #[cfg_attr(test, automock)] gibt an, dass das automock Attribut gesetzt werden sollte, wenn das Testen aktiviert ist. Dies weist darauf mockall hin, S3Impl dass ein Modell generiert werden soll, das benannt wirdMockS3Impl.

    • In diesem Beispiel ist die list_objects() Methode der Aufruf, den Sie verspotten möchten. automockerstellt automatisch eine expect_list_objects() Methode für Sie.

    #[allow(dead_code)] pub struct S3Impl { inner: s3::Client, } #[cfg_attr(test, automock)] impl S3Impl { #[allow(dead_code)] pub fn new(inner: s3::Client) -> Self { Self { inner } } #[allow(dead_code)] pub async fn list_objects( &self, bucket: &str, prefix: &str, continuation_token: Option<String>, ) -> Result<ListObjectsV2Output, s3::error::SdkError<ListObjectsV2Error>> { self.inner .list_objects_v2() .bucket(bucket) .prefix(prefix) .set_continuation_token(continuation_token) .send() .await } }
  5. Erstellen Sie die Testfunktionen in einem Modul mit dem Namentest.

    • Die Bedingung #[cfg(test)] gibt an, dass das Testmodul erstellt werden mockall soll, wenn das test true Attribut

    #[cfg(test)] mod test { use super::*; use mockall::predicate::eq; #[tokio::test] async fn test_single_page() { let mut mock = MockS3Impl::default(); mock.expect_list_objects() .with(eq("test-bucket"), eq("test-prefix"), eq(None)) .return_once(|_, _, _| { Ok(ListObjectsV2Output::builder() .set_contents(Some(vec![ // Mock content for ListObjectsV2 response s3::types::Object::builder().size(5).build(), s3::types::Object::builder().size(2).build(), ])) .build()) }); // Run the code we want to test with it let size = determine_prefix_file_size(mock, "test-bucket", "test-prefix") .await .unwrap(); // Verify we got the correct total size back assert_eq!(7, size); } #[tokio::test] async fn test_multiple_pages() { // Create the Mock instance with two pages of objects now let mut mock = MockS3Impl::default(); mock.expect_list_objects() .with(eq("test-bucket"), eq("test-prefix"), eq(None)) .return_once(|_, _, _| { Ok(ListObjectsV2Output::builder() .set_contents(Some(vec![ // Mock content for ListObjectsV2 response s3::types::Object::builder().size(5).build(), s3::types::Object::builder().size(2).build(), ])) .set_next_continuation_token(Some("next".to_string())) .build()) }); mock.expect_list_objects() .with( eq("test-bucket"), eq("test-prefix"), eq(Some("next".to_string())), ) .return_once(|_, _, _| { Ok(ListObjectsV2Output::builder() .set_contents(Some(vec![ // Mock content for ListObjectsV2 response s3::types::Object::builder().size(3).build(), s3::types::Object::builder().size(9).build(), ])) .build()) }); // Run the code we want to test with it let size = determine_prefix_file_size(mock, "test-bucket", "test-prefix") .await .unwrap(); assert_eq!(19, size); } }
    • Jeder Test verwendetlet mut mock = MockS3Impl::default();, um eine mock Instanz von zu erstellenMockS3Impl.

    • Es verwendet die expect_list_objects() Methode des Mocks (die automatisch von erstellt wurdeautomock), um das erwartete Ergebnis festzulegen, wenn die list_objects() Methode an anderer Stelle im Code verwendet wird.

    • Nachdem die Erwartungen festgelegt wurden, werden diese verwendet, um die Funktion durch Aufrufen zu testendetermine_prefix_file_size(). Der zurückgegebene Wert wird anhand einer Assertion überprüft, um zu bestätigen, dass er korrekt ist.

  6. Die determine_prefix_file_size() Funktion verwendet den Amazon S3 S3-Wrapper, um die Größe der Präfixdatei abzurufen:

    #[allow(dead_code)] pub async fn determine_prefix_file_size( // Now we take a reference to our trait object instead of the S3 client // s3_list: ListObjectsService, s3_list: S3, bucket: &str, prefix: &str, ) -> Result<usize, s3::Error> { let mut next_token: Option<String> = None; let mut total_size_bytes = 0; loop { let result = s3_list .list_objects(bucket, prefix, next_token.take()) .await?; // Add up the file sizes we got back for object in result.contents() { total_size_bytes += object.size().unwrap_or(0) as usize; } // Handle pagination, and break the loop if there are no more pages next_token = result.next_continuation_token.clone(); if next_token.is_none() { break; } } Ok(total_size_bytes) }

Der Typ S3 wird verwendet, um das verpackte SDK für Rust-Funktionen aufzurufen, um beide Funktionen zu unterstützen, S3Impl und MockS3Impl wenn HTTP-Anfragen gestellt werden. Der automatisch generierte Mock mockall meldet alle Testfehler, wenn das Testen aktiviert ist.

Den vollständigen Code für diese Beispiele finden Sie unter GitHub.

Simulieren Sie den HTTP-Verkehr mithilfe von statischer Wiedergabe

Die aws-smithy-runtime Kiste enthält eine Testdienstprogrammklasse namens. StaticReplayClient Diese HTTP-Client-Klasse kann anstelle des Standard-HTTP-Clients angegeben werden, wenn ein AWS-Service Objekt erstellt wird.

Bei der StaticReplayClient Initialisierung von geben Sie eine Liste von HTTP-Anforderungs- und Antwortpaaren als ReplayEvent Objekte an. Während der Test ausgeführt wird, wird jede HTTP-Anfrage aufgezeichnet und der Client gibt die nächste HTTP-Antwort, die in der nächsten in der Ereignisliste gefunden wurde, als Antwort des HTTP-Clients zurück. ReplayEvent Dadurch kann der Test mit bekannten Daten und ohne Netzwerkverbindung ausgeführt werden.

Statische Wiedergabe wird verwendet

Um Static Replay zu verwenden, müssen Sie keinen Wrapper verwenden. Ermitteln Sie stattdessen, wie der tatsächliche Netzwerkverkehr für die Daten aussehen sollte, die Ihr Test verwenden wird, und stellen Sie diese Verkehrsdaten zur Verfügung, damit sie sie jedes Mal verwenden können, wenn das SDK eine Anfrage vom Client ausgibt. StaticReplayClient AWS-Service

Anmerkung

Es gibt mehrere Möglichkeiten, den erwarteten Netzwerkverkehr zu erfassen, darunter die AWS CLI und viele Tools zur Analyse des Netzwerkverkehrs und Paket-Sniffer-Tools.

  • Erstellen Sie eine Liste von ReplayEvent Objekten, die die erwarteten HTTP-Anfragen und die Antworten angeben, die für sie zurückgegeben werden sollen.

  • Erstellen Sie eine StaticReplayClient mithilfe der im vorherigen Schritt erstellten HTTP-Transaktionsliste.

  • Erstellen Sie ein Konfigurationsobjekt für den AWS Client und geben Sie das StaticReplayClient als Config Objekt anhttp_client.

  • Erstellen Sie das AWS-Service Client-Objekt mithilfe der im vorherigen Schritt erstellten Konfiguration.

  • Führen Sie die Operationen, die Sie testen möchten, mit dem Serviceobjekt aus, das für die Verwendung von konfiguriert istStaticReplayClient. Jedes Mal, wenn das SDK eine API-Anfrage an sendet AWS, wird die nächste Antwort in der Liste verwendet.

    Anmerkung

    Die nächste Antwort in der Liste wird immer zurückgegeben, auch wenn die gesendete Anfrage nicht mit der Antwort im ReplayEvent Objektvektor übereinstimmt.

  • Wenn alle gewünschten Anfragen gestellt wurden, rufen Sie die StaticReplayClient.assert_requests_match() Funktion auf, um zu überprüfen, ob die vom SDK gesendeten Anfragen mit denen in der ReplayEvent Objektliste übereinstimmen.

Beispiel

Schauen wir uns die Tests für dieselbe determine_prefix_file_size() Funktion im vorherigen Beispiel an, verwenden aber Static Replay statt Mocking.

  1. Fügen Sie in einer Befehlszeile für Ihr Projektverzeichnis die aws-smithy-runtimeCrate als Abhängigkeit hinzu:

    $ cargo add aws-smithy-runtime --features test-util

    Dadurch wird die Kiste dem [dependencies] Abschnitt Ihrer Cargo.toml Datei hinzugefügt.

  2. Fügen Sie in Ihrer Quelldatei die aws_smithy_runtime Typen hinzu, die Sie benötigen.

    use aws_smithy_runtime::client::http::test_util::{ReplayEvent, StaticReplayClient}; use aws_smithy_types::body::SdkBody;
  3. Der Test beginnt mit der Erstellung der ReplayEvent Strukturen, die jede der HTTP-Transaktionen darstellen, die während des Tests stattfinden sollen. Jedes Ereignis enthält ein HTTP-Anforderungsobjekt und ein HTTP-Antwortobjekt, die die Informationen darstellen, mit denen AWS-Service sie normalerweise antworten würden. Diese Ereignisse werden an einen Aufruf übergeben anStaticReplayClient::new():

    let page_1 = ReplayEvent::new( http::Request::builder() .method("GET") .uri("https://test-bucket.s3.us-east-1.amazonaws.com/?list-type=2&prefix=test-prefix") .body(SdkBody::empty()) .unwrap(), http::Response::builder() .status(200) .body(SdkBody::from(include_str!("./testing/response_multi_1.xml"))) .unwrap(), ); let page_2 = ReplayEvent::new( http::Request::builder() .method("GET") .uri("https://test-bucket.s3.us-east-1.amazonaws.com/?list-type=2&prefix=test-prefix&continuation-token=next") .body(SdkBody::empty()) .unwrap(), http::Response::builder() .status(200) .body(SdkBody::from(include_str!("./testing/response_multi_2.xml"))) .unwrap(), ); let replay_client = StaticReplayClient::new(vec![page_1, page_2]);

    Das Ergebnis wird gespeichert inreplay_client. Dies stellt einen HTTP-Client dar, der dann vom SDK für Rust verwendet werden kann, indem er in der Konfiguration des Clients angegeben wird.

  4. Um den Amazon S3 S3-Client zu erstellen, rufen Sie die from_conf() Funktion der Client-Klasse auf, um den Client mithilfe eines Konfigurationsobjekts zu erstellen:

    let client: s3::Client = s3::Client::from_conf( s3::Config::builder() .behavior_version(BehaviorVersion::latest()) .credentials_provider(make_s3_test_credentials()) .region(s3::config::Region::new("us-east-1")) .http_client(replay_client.clone()) .build(), );

    Das Konfigurationsobjekt wird mit der http_client() Methode des Builders angegeben, und die Anmeldeinformationen werden mit der credentials_provider() Methode angegeben. Die Anmeldeinformationen werden mithilfe einer aufgerufenen Funktion erstelltmake_s3_test_credentials(), die eine falsche Struktur der Anmeldeinformationen zurückgibt:

    fn make_s3_test_credentials() -> s3::config::Credentials { s3::config::Credentials::new( "ATESTCLIENT", "astestsecretkey", Some("atestsessiontoken".to_string()), None, "", ) }

    Diese Anmeldeinformationen müssen nicht gültig sein, da sie nicht wirklich gesendet werden AWS.

  5. Führen Sie den Test aus, indem Sie die Funktion aufrufen, die getestet werden muss. In diesem Beispiel lautet der Name dieser Funktiondetermine_prefix_file_size(). Sein erster Parameter ist das Amazon S3 S3-Client-Objekt, das für seine Anfragen verwendet werden soll. Geben Sie daher den Client an, der mit dem StaticReplayClient so erstellt wurde, dass Anfragen von diesem bearbeitet werden, anstatt über das Netzwerk gesendet zu werden:

    let size = determine_prefix_file_size(client, "test-bucket", "test-prefix") .await .unwrap(); assert_eq!(19, size); replay_client.assert_requests_match(&[]);

    Wenn der Aufruf von abgeschlossen determine_prefix_file_size() ist, wird eine Bestätigung verwendet, um zu bestätigen, dass der zurückgegebene Wert dem erwarteten Wert entspricht. Dann wird die StaticReplayClient assert_requests_match() Methodenfunktion aufgerufen. Diese Funktion scannt die aufgezeichneten HTTP-Anfragen und bestätigt, dass sie alle mit denen übereinstimmen, die im ReplayEvent Objektarray angegeben wurden, das bei der Erstellung des Replay-Clients bereitgestellt wurde.

Den vollständigen Code für diese Beispiele finden Sie unter GitHub.

DatenschutzNutzungsbedingungen für die WebsiteCookie-Einstellungen
© 2025, Amazon Web Services, Inc. oder Tochtergesellschaften. Alle Rechte vorbehalten.