Tests mit einem Mock-Client schreiben

Hier erfahren Sie, wie Sie echte Clientimplementierungen stummschalten, um für Unit-Tests einen Mock einzufügen. Mit einem Mock-Client und den Google Cloud Client Libraries for Rust können Sie kontrollierte, zuverlässige Unit-Tests schreiben, bei denen keine Netzwerkaufrufe erfolgen und keine Abrechnungsgebühren anfallen.

Abhängigkeiten

Für Rust sind mehrere Mocking-Frameworks verfügbar. In dieser Anleitung wird mockall verwendet. Fügen Sie es als Entwicklungsabhängigkeit hinzu:

cargo add --dev mockall

Außerdem wird in dieser Anleitung der Speech-Client verwendet, um die Beispiele leichter verständlich zu machen. Diese Konzepte gelten jedoch für alle Clients.

Fügen Sie der Datei Cargo.toml die erforderlichen Abhängigkeiten hinzu:

cargo add google-cloud-speech-v2 google-cloud-lro

Client simulieren

Wenn Sie Ihren Code mit einem Mock-Client testen möchten, definieren Sie eine Mock-Struktur, konfigurieren das erwartete Verhalten für Ihr Testszenario und fügen diesen Mock dann in Ihre Anwendungslogik ein. Das folgende Beispiel veranschaulicht diesen Workflow.

Fügen Sie zuerst use-Anweisungen hinzu, um den Code zu vereinfachen:

use google_cloud_gax as gax;
use google_cloud_speech_v2 as speech;

Angenommen, die Anwendung hat eine Funktion, die den Speech-Client verwendet, um GetRecognizer aufzurufen, das Feld name der Anfrage festzulegen und die Serverantwort zu verarbeiten.

// An example application function.
//
// It makes an RPC, setting some field. In this case, it is the `GetRecognizer`
// RPC, setting the name field.
//
// It processes the response from the server. In this case, it extracts the
// display name of the recognizer.
async fn my_application_function(client: &speech::client::Speech) -> gax::Result<String> {
    client
        .get_recognizer()
        .set_name("invalid-test-recognizer")
        .send()
        .await
        .map(|r| r.display_name)
}

Sie können testen, wie die Anwendung mit verschiedenen Antworten vom Dienst umgeht.

Definieren Sie als Nächstes die Mock-Struktur. Diese Struktur implementiert das speech::stub::Speech-Trait.

mockall::mock! {
    #[derive(Debug)]
    Speech {}
    impl speech::stub::Speech for Speech {
        async fn get_recognizer(&self, req: speech::model::GetRecognizerRequest, _options: gax::options::RequestOptions) -> gax::Result<gax::response::Response<speech::model::Recognizer>>;
    }
}

Erstellen Sie eine Instanz des Mocks. Beachten Sie, dass das mockall::mock! Makro dem Namen der zuvor definierten Struktur das Präfix Mock voranstellt.

let mut mock = MockSpeech::new();

Legen Sie Erwartungen an den Mock fest. Sie können beispielsweise erwarten, dass der Code GetRecognizer mit einem bestimmten Namen aufruft und eine erfolgreiche Antwort vom Dienst simuliert.

mock.expect_get_recognizer()
    .withf(move |r, _|
        // Optionally, verify fields in the request.
        r.name == "invalid-test-recognizer")
    .return_once(|_, _| {
        Ok(gax::response::Response::from(
            speech::model::Recognizer::new().set_display_name("test-display-name"),
        ))
    });

Erstellen Sie einen Speech-Client mit dem Mock:

let client = speech::client::Speech::from_stub(mock);

Rufen Sie die Funktion auf:

let display_name = my_application_function(&client).await?;

Prüfen Sie die Ergebnisse:

assert_eq!(display_name, "test-display-name");

Fehler simulieren

Das Simulieren von Fehlern ähnelt dem Simulieren von Erfolgen. Um einen Fehler zu simulieren, ändern Sie das vom Mock zurückgegebene Ergebnis.

mock.expect_get_recognizer().return_once(|_, _| {
    // This time, return an error.
    use gax::error::Error;
    use gax::error::rpc::{Code, Status};
    let status = Status::default()
        .set_code(Code::NotFound)
        .set_message("Resource not found");
    Err(Error::service(status))
});

Ein mit from_stub() erstellter Client hat keine interne Wiederholungsschleife. Er gibt alle Fehler vom Stub direkt an die Anwendung zurück.

Nächste Schritte

Den vollständigen Code aus dieser Anleitung finden Sie in der Quelldatei im google-cloud-rust Repository auf GitHub.