Kelas Python Mengejek

王林
Lepaskan: 2024-08-28 18:32:30
asal
407 orang telah melayarinya

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
Salin selepas log masuk

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
Salin selepas log masuk

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

Salin selepas log masuk

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
Salin selepas log masuk

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
Salin selepas log masuk

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
Salin selepas log masuk

Semoga ini membantu! :)

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

sumber:dev.to
Kenyataan Laman Web ini
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
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan