Menulis pengujian menggunakan klien tiruan

Pelajari cara membuat stub implementasi klien nyata untuk menyuntikkan tiruan untuk pengujian unit. Menggunakan klien tiruan dengan Google Cloud Client Libraries for Rust memungkinkan Anda menulis pengujian unit yang terkontrol dan andal yang tidak melakukan panggilan jaringan atau menimbulkan biaya penagihan.

Dependensi

Ada beberapa framework tiruan yang tersedia untuk Rust. Panduan ini menggunakan mockall. Tambahkan sebagai dependensi pengembangan:

cargo add --dev mockall

Selain itu, panduan ini menggunakan klien Speech untuk mempermudah pemahaman contoh (tetapi konsep ini berlaku untuk semua klien).

Tambahkan dependensi yang diperlukan ke file Cargo.toml Anda:

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

Menyimulasikan klien

Untuk menguji kode dengan klien tiruan, Anda menentukan struct tiruan, mengonfigurasi perilaku yang diharapkan untuk skenario pengujian, lalu menyuntikkan tiruan tersebut ke dalam logika aplikasi. Contoh berikut menunjukkan alur kerja ini.

Pertama, tambahkan pernyataan use untuk menyederhanakan kode:

use google_cloud_gax as gax;
use google_cloud_speech_v2 as speech;

Asumsikan aplikasi memiliki fungsi yang menggunakan klien Speech untuk memanggil GetRecognizer, menetapkan kolom name permintaan, dan memproses respons server.

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

Anda dapat menguji cara aplikasi menangani berbagai respons dari layanan.

Selanjutnya, tentukan struktur tiruan. Struct ini mengimplementasikan trait speech::stub::Speech.

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

Buat instance tiruan. Perhatikan bahwa makro mockall::mock! menambahkan awalan Mock ke nama struct yang sebelumnya ditentukan.

let mut mock = MockSpeech::new();

Tetapkan ekspektasi pada tiruan. Misalnya, harapkan kode untuk memanggil GetRecognizer dengan nama tertentu dan simulasikan respons yang berhasil dari layanan.

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

Buat klien Speech menggunakan tiruan:

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

Memanggil fungsi:

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

Verifikasi hasilnya:

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

Menyimulasikan error

Menyimulasikan error mirip dengan menyimulasikan keberhasilan. Untuk menyimulasikan error, ubah hasil yang ditampilkan oleh tiruan.

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

Klien yang dibuat dengan from_stub() tidak memiliki loop percobaan ulang internal; klien mengembalikan semua error dari stub langsung ke aplikasi.

Langkah berikutnya

Untuk melihat kode lengkap dari panduan ini, lihat file sumber di repositori google-cloud-rust di GitHub.