"إذا أراد العامل أن يؤدي عمله بشكل جيد، فعليه أولاً أن يشحذ أدواته." - كونفوشيوس، "مختارات كونفوشيوس. لو لينجونج"
الصفحة الأمامية > برمجة > السخرية من دروس بايثون

السخرية من دروس بايثون

تم النشر بتاريخ 2024-11-03
تصفح:180

Mocking Python Classes

في الآونة الأخيرة، اضطررت إلى كتابة اختبارات الوحدة باستخدام Pytest لوحدة Python. تحتوي الوحدة على فئة حيث يتم تهيئة الفئات الأخرى داخل منشئها.

كالعادة قمت بإنشاء عنصر أساسي لهذا الفصل لتسهيل كتابة اختبار لكل طريقة فصل. في هذه المرحلة واجهت بعض المشكلات عندما حاولت الاستهزاء بالفئات المختلفة التي بدأت في المُنشئ. لم تنجح السخرية، ولا يزال يتم إنشاء مثيلات هذه الفئات.

بعد إجراء بعض الأبحاث والجمع بين بعض الحلول المختلفة التي وجدتها عبر الإنترنت، أريد أن أشارك كيف تمكنت من الاستهزاء بالفصول الدراسية.

حل

إليك مثال للفصل الذي حاولت الاستهزاء به:

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

نريد تعيين قيمة لكل حقل من هذه الفئة أثناء الاختبارات. يمكن أن تكون هذه القيمة بلا أو فئة وهمية، لكننا لا نريد بدء الفئتين ClassB وClassC.

في حالتنا، دعونا نقرر أن self.class_b وself.class_c يجب أن يكونا صورتين:

@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

لذلك يبدو عنصرًا أساسيًا لهذا الفصل الذي يخدم هدفنا كما يلي:

@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

الجزء المهم هو كيفية استخدام وظيفة patch.object، والتي هي من وحدة Unittest.mock في بايثون. يتم استخدامه في الاختبار لاستبدال سمة كائن معين مؤقتًا بقيمة وهمية أو بقيمة أخرى.

الحجج

  1. target=ClassA: الكائن (عادةً فئة) الذي نريد تصحيح سمته.
  2. السمة = "__init__": اسم السمة التي نريد تصحيحها.
  3. return_value=None: استبدال طريقة __init__ بوظيفة لا تفعل شيئًا

بهذه الطريقة يمكننا إنشاء متغيرات ساخرة في تركيباتنا.
اقرأ المزيد عن patch.object

نصائح الاختبار

لقد كتبت هذا البرنامج التعليمي لهذا النوع من الحالات حيث، لأي سبب من الأسباب، لا يمكننا تغيير رمز الفئة أ. ومع ذلك، أوصي بشكل عام بتعديل الكود إن أمكن، ليس لتغيير المنطق، ولكن لجعله أكثر قابلية للاختبار .

إليك بعض الأمثلة حول كيفية تعديل الفئة (أ) لجعلها أكثر قابلية للاختبار:

الخيار 1: تمرير مثيلات الفئة B والفئة C كمعلمات.
بهذه الطريقة، عندما نكتب التركيبة، يمكننا تمرير نماذج وهمية بدلاً من المثيلات.

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

الخيار الثاني: إنشاء متغير منطقي يشير إلى وضع الاختبار.
بهذه الطريقة يمكننا أن نقرر أي الحقول من الفئة أ سوف تحصل أو لن تحصل على قيمة عند بدئها.

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

الخيار الثالث: إجراء بدء الفصل الدراسي بطريقة منفصلة.
يمنحنا هذا الأسلوب خيار تجنب استدعاء متغيرات set_class_variables في وحدة الاختبار.

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

آمل أن يساعد هذا! :)

بيان الافراج تم نشر هذه المقالة على: https://dev.to/chen_ashkenazi/mocking-python-classes-4h96?1 إذا كان هناك أي انتهاك، يرجى الاتصال بـ [email protected] لحذفه
أحدث البرنامج التعليمي أكثر>

تنصل: جميع الموارد المقدمة هي جزئيًا من الإنترنت. إذا كان هناك أي انتهاك لحقوق الطبع والنشر الخاصة بك أو الحقوق والمصالح الأخرى، فيرجى توضيح الأسباب التفصيلية وتقديم دليل على حقوق الطبع والنشر أو الحقوق والمصالح ثم إرسالها إلى البريد الإلكتروني: [email protected]. سوف نتعامل مع الأمر لك في أقرب وقت ممكن.

Copyright© 2022 湘ICP备2022001581号-3