समस्या
एक वर्ग उस वर्ग के उदाहरणों की विशेषताओं संरक्षण नहीं है पैच करने के लिए autospec=True
साथ mock.patch
का उपयोग करना "AttributeError नकली वस्तु कोई गुण नहीं है"।एक वर्ग पैदावार पैचिंग: जब उदाहरण तक पहुँचने का श्रेय
विवरण
मैं एक वर्ग Bar
कि एक Bar
वस्तु विशेषता के रूप में वर्ग Foo
का एक उदाहरण को दर्शाता है परीक्षण करने के लिए कोशिश कर रहा हूँ foo
कहा जाता है। परीक्षण के तहत Bar
विधि bar
कहा जाता है; यह Foo
उदाहरण Bar
से संबंधित विधि foo
पर कॉल करता है। इस परीक्षण में, मैं Foo
मजाक कर रहा हूँ, के रूप में मैं केवल परीक्षण करने के लिए है कि Bar
सही Foo
सदस्य तक पहुँच रहा है चाहता हूँ:
import unittest
from mock import patch
class Foo(object):
def __init__(self):
self.foo = 'foo'
class Bar(object):
def __init__(self):
self.foo = Foo()
def bar(self):
return self.foo.foo
class TestBar(unittest.TestCase):
@patch('foo.Foo', autospec=True)
def test_patched(self, mock_Foo):
Bar().bar()
def test_unpatched(self):
assert Bar().bar() == 'foo'
वर्गों और तरीकों ठीक (test_unpatched
गुजरता) काम करते हैं, लेकिन जब मैं में फू करने की कोशिश एक टेस्ट केस autospec=True
का उपयोग कर (दोनों nosetests और pytest का उपयोग कर परीक्षण किया गया), मैं का सामना "AttributeError: नकली वस्तु कोई गुण नहीं है 'foo'"
19:39 $ nosetests -sv foo.py
test_patched (foo.TestBar) ... ERROR
test_unpatched (foo.TestBar) ... ok
======================================================================
ERROR: test_patched (foo.TestBar)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/usr/local/lib/python2.7/dist-packages/mock.py", line 1201, in patched
return func(*args, **keywargs)
File "/home/vagrant/dev/constellation/test/foo.py", line 19, in test_patched
Bar().bar()
File "/home/vagrant/dev/constellation/test/foo.py", line 14, in bar
return self.foo.foo
File "/usr/local/lib/python2.7/dist-packages/mock.py", line 658, in __getattr__
raise AttributeError("Mock object has no attribute %r" % name)
AttributeError: Mock object has no attribute 'foo'
दरअसल, जब मैं mock_Foo.return_value.__dict__
प्रिंट आउट, मैं देख सकता हूँ कि foo
नहीं है बच्चों की सूची में या तरीकों:
{'_mock_call_args': None,
'_mock_call_args_list': [],
'_mock_call_count': 0,
'_mock_called': False,
'_mock_children': {},
'_mock_delegate': None,
'_mock_methods': ['__class__',
'__delattr__',
'__dict__',
'__doc__',
'__format__',
'__getattribute__',
'__hash__',
'__init__',
'__module__',
'__new__',
'__reduce__',
'__reduce_ex__',
'__repr__',
'__setattr__',
'__sizeof__',
'__str__',
'__subclasshook__',
'__weakref__'],
'_mock_mock_calls': [],
'_mock_name': '()',
'_mock_new_name': '()',
'_mock_new_parent': <MagicMock name='Foo' spec='Foo' id='38485392'>,
'_mock_parent': <MagicMock name='Foo' spec='Foo' id='38485392'>,
'_mock_wraps': None,
'_spec_class': <class 'foo.Foo'>,
'_spec_set': None,
'method_calls': []}
autospec की मेरी समझ है कि, अगर यह सच है, पैच चश्मा रिकर्सिवली लागू करना चाहिए। चूंकि foo वास्तव में फू उदाहरणों की विशेषता है, क्या इसे पैच नहीं किया जाना चाहिए? यदि नहीं, तो मैं फू उदाहरणों के गुणों को संरक्षित करने के लिए फू मॉक कैसे प्राप्त करूं?
नोट:
यह एक तुच्छ उदाहरण है कि मूल समस्या से पता चलता है। हकीकत में, मैं एक थर्ड पार्टी मॉड्यूल का मज़ाक उड़ा रहा हूं। क्लास - consul.Consul
- जिसका ग्राहक मैं अपने पास एक कंसुल रैपर वर्ग में तत्काल हूं। चूंकि मैं कंसुल मॉड्यूल को बनाए नहीं रखता, इसलिए मैं अपने परीक्षणों के अनुरूप स्रोत को संशोधित नहीं कर सकता (मैं वास्तव में वैसे भी ऐसा नहीं करना चाहता)। इसके लायक होने के लिए, consul.Consul()
एक कंसुल क्लाइंट लौटाता है, जिसमें kv
विशेषता है - consul.Consul.KV
का एक उदाहरण। kv
में एक विधि get
है, जिसे मैं अपने कंसुल क्लास में एक उदाहरण विधि get_key
में लपेट रहा हूं। consul.Consul
पैच करने के बाद, AttributeError की वजह से विफल होने के लिए कॉल: मॉक ऑब्जेक्ट में कोई विशेषता kv नहीं है।
संसाधन पहले से ही जांचा गया:
http://mock.readthedocs.org/en/latest/helpers.html#autospeccing http://mock.readthedocs.org/en/latest/patch.html
उस वर्ग के उदाहरण बनाने के लिए नकली की आवश्यकता होगी। यह कभी भी एक अच्छा विचार नहीं है, क्योंकि इसे उस कोड को निष्पादित करने की आवश्यकता होगी जिसे आप पहली जगह में नकली के साथ बदलने की कोशिश कर रहे थे। –