Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Kelas Python Mengejek

Kelas Python Mengejek

王林
王林asal
2024-08-28 18:32:30251semak imbas

Mocking Python Classes

Kebelakangan ini, saya terpaksa menulis ujian unit menggunakan Pytest untuk modul Python. Modul ini mengandungi kelas di mana kelas lain dimulakan dalam pembinanya.

Seperti biasa saya mencipta lekapan untuk kelas ini untuk memudahkan menulis ujian bagi setiap kaedah kelas. Pada ketika ini saya menghadapi beberapa isu apabila saya cuba mengejek kelas berbeza yang dimulakan dalam pembina. Ejekan itu tidak berkesan dan contoh kelas ini masih dibuat.

Selepas beberapa penyelidikan dan menggabungkan beberapa penyelesaian berbeza yang saya temui dalam talian, saya ingin berkongsi bagaimana saya berjaya mengejek kelas.

Penyelesaian

Berikut ialah contoh kelas yang saya cuba ejek:

class ClassA:
    def __init__(self):
        self.class_b = ClassB()
        self.class_c = ClassC()
        self.count = 0

Kami mahu menetapkan nilai untuk setiap medan kelas ini semasa ujian. Nilai ini boleh menjadi Tiada atau olok-olok kelas, tetapi kami tidak mahu permulaan kelas ClassB dan ClassC.

Dalam kes kita, mari kita tentukan bahawa self.class_b dan self.class_c sepatutnya menjadi olok-olok:

@pytest.fixture
def mock_class_b():
    class_b = Mock(spec=ClassB)
    return class_b

@pytest.fixture
def mock_class_c():
    class_c = Mock(spec=ClassC)
    return class_c

Jadi perlawanan untuk kelas ini yang memenuhi matlamat kami kelihatan seperti ini:

@pytest.fixture
def class_a_mock(mock_class_b, mock_class_c):
    with patch.object(target=ClassA, attribute="__init__", return_value=None) as mock_init:
        class_a = ClassA()
        class_a.class_b = mock_class_b
        class_a.class_c = mock_class_c
        class_b.count = 0
        return class_a

Bahagian penting ialah cara menggunakan fungsi patch.object, iaitu daripada modul unittest.mock dalam Python. Ia digunakan dalam ujian untuk menggantikan sementara atribut objek tertentu dengan olok-olok atau nilai lain.

Hujah

  1. target=ClassA: objek (biasanya kelas) yang atributnya ingin kita tampal.
  2. attribute="__init__": nama atribut yang ingin kita tampal.
  3. return_value=Tiada: menggantikan kaedah __init__ dengan fungsi yang tidak melakukan apa-apa

Dengan cara ini kita boleh mencipta pembolehubah ejek dalam perlawanan kita.
Baca lebih lanjut tentang patch.object

Petua Ujian

Saya menulis tutorial ini untuk kes seperti ini di mana, atas sebarang sebab, kami tidak boleh menukar kod Kelas A. Walau bagaimanapun, saya biasanya mengesyorkan mengubah suai kod jika boleh, bukan untuk menukar logik, tetapi untuk menjadikannya lebih boleh diuji .

Berikut ialah beberapa contoh cara mengubah suai Kelas A untuk menjadikannya lebih boleh diuji:

Pilihan 1: Lulus tika kelas B dan kelas C sebagai parameter.
Dengan cara ini, apabila kita menulis perlawanan, kita boleh melepasi olok-olok dan bukannya kejadian.

class ClassA:
    def __init__(self, class_b_instance, class_c_instance):
        self.class_b = class_b_instance
        self.class_c = class_c_instance
        self.count = 0

Pilihan 2: Buat pembolehubah Boolean yang menunjukkan mod ujian.
Dengan cara ini kita boleh memutuskan medan kelas A yang akan atau tidak akan mendapat nilai apabila ia dimulakan.

class ClassA:
    def __init__(self, test_mode=False):
        if not test_mode:
            self.class_b = ClassB()
            self.class_c = ClassC()
        self.count = 0

Pilihan 3: Buat permulaan kelas dalam kaedah yang berasingan.
Pendekatan ini memberi kita pilihan untuk mengelak daripada memanggil set_class_variables dalam modul ujian.

class ClassA:
    def __init__(self):
        self.class_b = None
        self.class_c = None
        self.count = None

    def set_class_variables(self):
        self.class_b = ClassB()
        self.class_c = ClassC()
        self.count = 0

Semoga ini membantu! :)

Atas ialah kandungan terperinci Kelas Python Mengejek. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn