بيثون ونيتست وهمية:هل من الممكن أن يسخر من قيمة الحجج الافتراضية طريقة في وقت الاختبار?

StackOverflow https://stackoverflow.com//questions/24021491

  •  21-12-2019
  •  | 
  •  

سؤال

لدي طريقة تقبل الوسائط الافتراضية:

def build_url(endpoint, host=settings.DEFAULT_HOST):
    return '{}{}'.format(host, endpoint)

لدي حالة اختبار تمارس هذه الطريقة:

class BuildUrlTestCase(TestCase):
    def test_build_url(self):
        """ If host and endpoint are supplied result should be 'host/endpoint' """

        result = build_url('/end', 'host')
        expected = 'host/end'

        self.assertEqual(result,expected)

     @patch('myapp.settings')
     def test_build_url_with_default(self, mock_settings):
        """ If only endpoint is supplied should default to settings"""
        mock_settings.DEFAULT_HOST = 'domain'

        result = build_url('/end')
        expected = 'domain/end'

        self.assertEqual(result,expected)

إذا قمت بإسقاط نقطة تصحيح في build_url وفحص هذه السمة settings.DEFAULT_HOST إرجاع قيمة سخر.ومع ذلك ، يستمر الاختبار في الفشل ويشير التأكيد إلى host يتم تعيين القيمة من بلدي الفعلي settings.py.أعرف أن هذا لأن host يتم تعيين وسيطة الكلمات الرئيسية في وقت الاستيراد ولا يتم اعتبار وهمية.

المصحح

(Pdb) settings
<MagicMock name='settings' id='85761744'>                                                                                                                                                                                               
(Pdb) settings.DEFAULT_HOST
'domain'
(Pdb) host
'host-from-settings.com'                                                                                                                                                 

هل هناك طريقة لتجاوز هذه القيمة في وقت الاختبار حتى أتمكن من ممارسة المسار الافتراضي مع سخر settings كائن?

هل كانت مفيدة؟

المحلول

وظائف تخزين القيم الافتراضية المعلمة في func_defaults السمة عندما يتم تعريف الدالة ، حتى تتمكن من تصحيح ذلك.شيء من هذا القبيل

def test_build_url(self):
    """ If only endpoint is supplied should default to settings"""

    # Use `func_defaults` in Python2.x and `__defaults__` in Python3.x.
    with patch.object(build_url, 'func_defaults', ('domain',)):
      result = build_url('/end')
      expected = 'domain/end'

    self.assertEqual(result,expected)

أنا استخدم patch.object كمدير سياق بدلا من مصمم ديكور لتجنب تمرير كائن التصحيح غير الضروري كوسيطة إلى test_build_url.

نصائح أخرى

لقد طبقت الإجابة الأخرى على هذا السؤال ، ولكن بعد مدير السياق ، لم تكن الوظيفة المصححة هي نفسها كما كانت من قبل.

تبدو وظيفتي المصححة كما يلي:

def f(foo=True):
    pass

في اختباري ، فعلت هذا:

with patch.object(f, 'func_defaults', (False,)):

عند الاتصال f بعد (وليس في) مدير السياق ، ذهب الافتراضي تماما بدلا من العودة إلى القيمة السابقة.الاتصال f دون الحجج أعطى الخطأ TypeError: f() takes exactly 1 argument (0 given)

بدلا من ذلك ، أنا فقط فعلت هذا قبل الاختبار:

f.func_defaults = (False,)

وهذا بعد اختباري:

f.func_defaults = (True,)

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

# mymodule.py
def myfunction(arg=17):
    return arg

# test_mymodule.py
from functools import partial
from mock import patch

import mymodule

class TestMyModule(TestCase):
    def test_myfunc(self):
        patched = partial(mymodule.myfunction, arg=23)
        with patch('mymodule.myfunction', patched):
            self.assertEqual(23, mymodule.myfunction())  # Passes; default overridden
        self.assertEqual(17, mymodule.myfunction()) # Also passes; original default restored

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

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top