Lewati ke konten utama

Tutorial pytest-mock: Panduan Pemula untuk Mocking di Python

Pelajari cara menggunakan pytest-mock, dari penyiapan dan dasar-dasar hingga teknik lanjutan untuk pengujian yang praktis.
Diperbarui 28 Sep 2026  · 15 mnt Baca

Jelajahi bersama AI

ChatGPTClaudePerplexity

Seiring proyek Python Anda berkembang dalam kompleksitas dan ukuran, pentingnya pengujian yang andal juga meningkat. Pengujian membantu memastikan kode Anda bekerja sebagaimana mestinya dan menjaga kualitas di seluruh bagian aplikasi.

Saat aplikasi Anda berinteraksi dengan berbagai jenis basis data atau API eksternal seperti OpenAI GPT atau Anthropic Claude, menguji dependensi ini bisa menjadi tantangan. Di sinilah mocking sangat berguna.

Mocking memungkinkan Anda mensimulasikan objek, fungsi, dan perilaku, sehingga pengujian menjadi lebih terisolasi dan dapat diprediksi. Ini juga memungkinkan Anda berfokus pada fungsi spesifik yang ingin diuji dengan mengisolasinya dari dependensi yang dapat menimbulkan kompleksitas atau perilaku tak terduga.

Dalam blog ini, Anda akan mempelajari cara menggunakan pytest-mock, plugin yang kuat untuk pytest, untuk menerapkan mock dalam pengujian Python Anda secara efisien. Pada akhir tutorial ini, Anda akan siap menambahkan teknik mocking ke kasus uji Anda, sehingga menjadi lebih kuat.

Apa itu pytest-mock?

pytest-mock adalah plugin untuk kerangka kerja pengujian Python populer pytest yang memberikan akses mudah ke kemampuan mocking. Ini dibangun di atas unittest bawaan Python, menyederhanakan proses mocking selama pengujian.

logo kerangka kerja pytest

logo kerangka kerja pytest

pytest-mock meningkatkan keterbacaan dan memudahkan penerapan mock dalam pengujian dengan pendekatan yang lebih native terhadap pytest. Baik Anda perlu me-mock fungsi individual, metode kelas, atau seluruh objek, pytest-mock menyediakan fleksibilitas yang diperlukan untuk pengujian efektif tanpa kompleksitas tambahan.

Salah satu alasan utama keterbacaan pytest-mock adalah gaya pengujian deklaratifnya, yang memungkinkan Anda menentukan panggilan dan perilaku yang diharapkan langsung dalam tes. Ini membuat kode lebih mudah ditulis, dibaca, dan dipelihara sekaligus tetap tangguh terhadap perubahan implementasi yang tidak mengubah perilaku eksternal kode.

Menyiapkan pytest-mock

Membuat lingkungan virtual untuk proyek Anda adalah praktik terbaik untuk memastikan dependensi terisolasi. Jika Anda belum menyiapkan lingkungan baru, Anda dapat membuatnya dengan conda menggunakan perintah berikut:

# create a conda environment
conda create --name yourenvname python=3.11
# activate conda environment
conda activate yourenvname

Menginstal pytest dan pytest-mock

Instal pytest dan pytest-mock langsung di lingkungan Anda menggunakan pip atau conda:

pip install pytest
pip install pytest-mock

Mengonfirmasi instalasi

Setelah menginstal pytest dan pytest-mock, verifikasi bahwa instalasi berhasil dengan menjalankan perintah berikut:

pytest --version

Dasar-dasar Mocking dengan pytest-mock

Mocking dapat dipahami sebagai membuat versi "dummy" dari sebuah komponen yang meniru perilaku nyata. 

Ini sangat membantu ketika Anda perlu menguji bagaimana fungsi atau kelas berinteraksi dengan komponen eksternal seperti basis data atau API eksternal.

Pengantar mocking

Sebuah objek mock mensimulasikan perilaku objek nyata. Ini sering digunakan dalam unit test untuk mengisolasi komponen dan menguji perilakunya tanpa mengeksekusi kode dependen. 

Sebagai contoh, Anda mungkin menggunakan objek mock untuk mensimulasikan panggilan basis data tanpa benar-benar terhubung ke basis data.

Mocking sangat berguna ketika objek asli:

  • Sulit dibuat atau dikonfigurasi.
  • Memakan waktu untuk digunakan (misalnya, mengakses basis data jarak jauh).
  • Memiliki efek samping yang harus dihindari selama pengujian (misalnya, mengirim email, menimbulkan biaya).

Menggunakan fixture mocker

pytest-mock menyediakan fixture mocker, yang memudahkan pembuatan dan pengendalian objek mock. Fixture mocker sangat kuat dan terintegrasi ke dalam pengujian pytest Anda.

💡Apa itu fixture? 

Dalam Python, fixture adalah komponen yang dapat digunakan kembali untuk menyiapkan dan membersihkan sumber daya yang dibutuhkan pengujian, seperti basis data atau berkas. Fixture memastikan konsistensi, mengurangi duplikasi, dan menyederhanakan penyiapan pengujian.

Mari kita lihat contohnya:

def fetch_weather_data(api_client):
    response = api_client.get("https://api.weather.com/data")
    if response.status_code == 200:
        return response.json()
    else:
        return None

Fungsi fetch_weather_data bergantung pada API cuaca eksternal untuk mengambil data, namun memanggil API saat pengujian bisa menimbulkan biaya yang tidak perlu. 

Untuk menghindari hal ini, Anda dapat menggunakan mocking untuk mensimulasikan perilaku API dalam pengujian, memastikan aplikasi diuji tanpa melakukan panggilan eksternal. Berikut cara mocking membantu:

def test_fetch_weather_data(mocker):
    # Create a mock API client
    mock_api_client = mocker.Mock()

    # Mock the response of the API client
    mock_response = mocker.Mock()
    mock_response.status_code = 200
    mock_response.json.return_value = {"temperature": "20C", "condition": "Sunny"}

    # Set the mock API client to return the mocked response
    mock_api_client.get.return_value = mock_response

    # Call the function with the mock API client
    result = fetch_weather_data(mock_api_client)

    # Assert that the correct data is returned
    assert result == {"temperature": "20C", "condition": "Sunny"}

    mock_api_client.get.assert_called_once_with("https://api.weather.com/data")

Dalam test_fetch_weather_data(), kita menggunakan fixture mocker untuk membuat klien API mock mock_api_client dan mock_response. Respons mock dikonfigurasi untuk meniru panggilan API nyata dengan mengembalikan status kode 200 dan data JSON yang berisi informasi cuaca. 

Metode get dari klien API mock diatur untuk mengembalikan respons mock ini. Saat fetch_weather_data() diuji, fungsi berinteraksi dengan klien API mock alih-alih melakukan panggilan API sebenarnya. 

Pendekatan ini memastikan fungsi berperilaku sesuai harapan sekaligus menjaga pengujian tetap cepat, hemat biaya, dan independen dari sistem eksternal. 

Pernyataan assert di akhir memverifikasi bahwa data yang dikembalikan sesuai dengan keluaran yang diharapkan.

Baris terakhir, mock_api_client.get.assert_called_once_with("https://api.weather.com/data"), secara khusus memeriksa bahwa metode get dari klien API mock dipanggil tepat satu kali dan dengan argumen yang benar. Ini membantu memastikan bahwa fungsi berinteraksi dengan API dengan cara yang diharapkan, menambahkan lapisan validasi tambahan pada pengujian.

Kasus Penggunaan Umum untuk pytest-mock

Mocking berguna dalam berbagai skenario, termasuk unit test di mana Anda perlu mengisolasi fungsi atau komponen tertentu. Mari lihat beberapa kasus penggunaan umum:

1. Mocking fungsi atau metode kelas

Anda mungkin perlu menguji sebuah fungsi yang bergantung pada fungsi atau metode lain, tetapi Anda ingin mengendalikan perilakunya selama pengujian. Mocking memungkinkan Anda mengganti dependensi tersebut dengan perilaku yang telah ditentukan:

# production code
def calculate_discount(price, discount_provider):
    discount = discount_provider.get_discount()
    return price - (price * discount / 100)

# test code
def test_calculate_discount(mocker):
    # Mock the get_discount method
    mock_discount_provider = mocker.Mock()
    mock_discount_provider.get_discount.return_value = 10  # Mocked discount value
    # Call the function with the mocked dependency
    result = calculate_discount(100, mock_discount_provider)
    # Assert the calculated discount is correct
    assert result == 90
    mock_discount_provider.get_discount.assert_called_once()

Dalam pengujian ini, metode get_discount() dari discount_provider di-mock untuk mengembalikan nilai yang telah ditentukan (10%). Ini mengisolasi fungsi calculate_discount() dari implementasi sebenarnya dari discount_provider.

2. Mocking kode yang bergantung pada waktu

Saat menguji fungsi yang melibatkan waktu atau penundaan, me-mock metode terkait waktu membantu menghindari penantian atau manipulasi waktu nyata:

# production code
import time
def long_running_task():
    time.sleep(5)  # Simulate a long delay
    return "Task Complete"

# test code
def test_long_running_task(mocker):
    # Mock the sleep function in the time module
    mocker.patch("time.sleep", return_value=None)
    # Call the function
    result = long_running_task()
    # Assert the result is correct
    assert result == "Task Complete"

Di sini, time.sleep dipatch untuk melewati penundaan sebenarnya selama pengujian. Ini memastikan pengujian berjalan cepat tanpa menunggu 5 detik.

3. Mocking atribut objek

Terkadang, Anda mungkin ingin me-mock perilaku atribut atau properti sebuah objek untuk mensimulasikan kondisi yang berbeda selama pengujian:

# production code
class User:
    def __init__(self, name, age):
        self.name = name
        self.age = age
    @property
    def is_adult(self):
        return self.age >= 18

# test code
def test_user_is_adult(mocker):
    # Create a User object
    user = User(name="Alice", age=17)
    # Mock the is_adult property
    mocker.patch.object(User, "is_adult", new_callable=mocker.PropertyMock, return_value=True)
    # Assert the mocked property value
    assert user.is_adult is True

Dalam contoh ini, properti is_adult() dari kelas User di-mock untuk mengembalikan True, terlepas dari usia sebenarnya. Ini berguna untuk menguji skenario yang bergantung pada status objek.

Teknik Mocking Lanjutan dengan pytest-mock

Setelah Anda nyaman dengan mocking dasar, pytest-mock menawarkan kemampuan lanjutan untuk menangani skenario yang lebih kompleks.

1. Mock side effect

Mock tidak hanya dapat mensimulasikan nilai kembalian—mock juga dapat meniru perilaku seperti melempar pengecualian atau mengubah nilai kembalian secara dinamis. Ini dicapai dengan menambahkan “side effect” pada mock:

import pytest

# production code
def process_payment(payment_gateway, amount):
    response = payment_gateway.charge(amount)
    if response == "Success":
        return "Payment processed successfully"
    else:
        raise ValueError("Payment failed")

# test code
def test_process_payment_with_side_effects(mocker):
    # Mock the charge method of the payment gateway
    mock_payment_gateway = mocker.Mock()
    # Add side effects: Success on first call, raise exception on second call
    mock_payment_gateway.charge.side_effect = ["Success", ValueError("Insufficient funds")]
    # Test successful payment
    assert process_payment(mock_payment_gateway, 100) == "Payment processed successfully"
    # Test payment failure
    with pytest.raises(ValueError, match="Insufficient funds"):
        process_payment(mock_payment_gateway, 200)
    # Verify the mock's behavior
    assert mock_payment_gateway.charge.call_count == 2

Properti side_effect memungkinkan mock mengembalikan nilai berbeda atau melempar pengecualian pada pemanggilan berikutnya. Dalam contoh ini, panggilan pertama ke charge mengembalikan "Success", sementara panggilan kedua melempar ValueError. Ini berguna untuk menguji berbagai skenario dalam satu pengujian.

2. Melakukan spying pada fungsi

Spying memungkinkan Anda melacak bagaimana fungsi nyata dipanggil, termasuk jumlah panggilan dan argumen yang diteruskan. Ini sangat berguna saat Anda ingin memastikan sebuah fungsi dipanggil seperti yang diharapkan sambil tetap mengeksekusi logika aslinya:

# production code
def log_message(logger, message):
    logger.info(message)
    return f"Logged: {message}"

# test code
def test_log_message_with_spy(mocker):
    # Spy on the info method of the logger
    mock_logger = mocker.Mock()
    spy_info = mocker.spy(mock_logger, "info")
    # Call the function
    result = log_message(mock_logger, "Test message")
    # Assert the returned value
    assert result == "Logged: Test message"
    # Verify the spy behavior
    spy_info.assert_called_once_with("Test message")
    assert spy_info.call_count == 1

Metode spy() melacak bagaimana sebuah metode nyata dipanggil tanpa mengubah perilakunya. Di sini, kita melakukan spying pada metode info dari logger untuk memastikan metode tersebut dipanggil dengan pesan yang benar sambil tetap membiarkan metode dijalankan secara normal.

Praktik Terbaik Menggunakan pytest-mock

Mocking sangat kuat, tetapi penggunaan yang ceroboh dapat menimbulkan masalah dalam pengujian Anda. Berikut beberapa praktik terbaik yang saya sarankan untuk diikuti:

1. Hindari over-mocking

Menggunakan terlalu banyak mock dapat menghasilkan pengujian yang rapuh yang rusak saat kode internal berubah, bahkan jika perilaku eksternal tidak berubah. Usahakan hanya me-mock yang diperlukan dan andalkan implementasi nyata kapan pun memungkinkan.

Over-mocking dapat membuat pengujian Anda sangat bergantung pada detail implementasi kode, yang berarti bahkan refactoring kecil pun dapat menyebabkan pengujian gagal tanpa alasan. Sebaliknya, fokuslah me-mock hanya bagian sistem yang bersifat eksternal atau memiliki efek samping signifikan.

2. Gunakan konvensi penamaan yang jelas

Saat me-mock objek, gunakan nama yang deskriptif untuk mock Anda. Ini membuat pengujian lebih mudah dibaca dan dipelihara. Misalnya, alih-alih menggunakan nama generik seperti mock_function(), gunakan sesuatu yang lebih deskriptif, seperti mock_api_response().

Konvensi penamaan yang jelas membantu orang lain memahami tujuan tiap mock, mengurangi kebingungan dan memudahkan pemeliharaan rangkaian pengujian dari waktu ke waktu.

3. Jaga pengujian tetap sederhana dan terfokus

Setiap pengujian harus fokus pada satu perilaku atau skenario. Ini menyederhanakan debug dan membuat pengujian Anda mudah dipahami. Pengujian yang terfokus dengan baik lebih mungkin memberikan umpan balik yang jelas saat ada masalah, sehingga memudahkan identifikasi dan perbaikan.

Kesimpulan

Dalam blog ini, kita membahas dasar-dasar mocking dengan pytest-mock dan mempelajari cara menggunakannya untuk meningkatkan pengujian Python. Kita mencakup segala hal mulai dari mocking dasar atas fungsi dan metode hingga teknik lebih lanjut seperti menambahkan side effect dan melakukan spying pada fungsi.

Mocking adalah alat penting untuk membuat pengujian yang andal dan mudah dipelihara, terutama saat bekerja dengan sistem kompleks atau dependensi eksternal. Dengan memasukkan pytest-mock ke dalam proyek Anda, Anda dapat menulis pengujian yang lebih terisolasi, dapat diprediksi, dan lebih mudah dipelihara.

Untuk terus mengembangkan keterampilan pengujian Anda, saya sarankan mengecek kursus gratis Introduction to Testing in Python di Datacamp.

FAQs

Apa perbedaan mocking dengan menguji komponen nyata?

Mocking menggantikan komponen nyata dengan yang disimulasikan, memungkinkan pengujian yang terisolasi dan hemat biaya tanpa bergantung pada sistem eksternal atau data nyata.

Bisakah saya menggunakan pytest-mock dengan kerangka kerja pengujian lain?

pytest-mock dirancang khusus untuk pytest dan terintegrasi mulus dengannya, namun dibangun di atas unittest.mock Python, yang dapat digunakan secara mandiri.

Apakah fixture wajib untuk mocking di pytest-mock?

Meskipun fixture seperti mocker meningkatkan efisiensi mocking, Anda tetap dapat menggunakan unittest.mock langsung di pytest tanpa fixture, meski dengan integrasi yang lebih rendah.


Moez Ali's photo
Author
Moez Ali
LinkedIn
Twitter

Data Scientist, Pendiri & Kreator PyCaret

Topik
Python

Pelajari lebih lanjut tentang Python dengan kursus-kursus ini!

Kursus

Pengantar Python untuk Pengembang

3 jam
185.5K
Kuasai dasar-dasar pemrograman dalam Python. Tidak diperlukan pengetahuan sebelumnya!
Lihat DetailRight Arrow
Mulai Kursus
Lihat SelengkapnyaRight Arrow
Terkait

blogs

Tutorial Korelasi di R

Dapatkan pengenalan dasar-dasar korelasi di R: pelajari lebih lanjut tentang koefisien korelasi, matriks korelasi, plotting korelasi, dan sebagainya.
David Woods's photo

David Woods

13 mnt

blogs

Spaghetti Plot dan Jalur Badai

Temukan alasan mengapa Anda sebaiknya (tidak) menggunakan spaghetti plot untuk menyampaikan ketidakpastian jalur prediksi badai serta dampaknya terhadap interpretasi.
Hugo Bowne-Anderson's photo

Hugo Bowne-Anderson

13 mnt

blogs

40 Pertanyaan Wawancara DBMS Teratas di 2026

Kuasai pertanyaan wawancara basis data, dari konsep SQL dasar hingga skenario desain sistem tingkat lanjut. Panduan mendalam ini mencakup semua yang Anda perlukan untuk sukses di wawancara DBMS dan meraih peran berikutnya.
Dario Radečić's photo

Dario Radečić

15 mnt

blogs

12 Alternatif ChatGPT Terbaik yang Bisa Anda Coba pada 2026

Artikel ini menyajikan daftar alternatif ChatGPT yang akan meningkatkan produktivitas Anda.
Javier Canales Luna's photo

Javier Canales Luna

14 mnt

Lihat SelengkapnyaLihat Selengkapnya