2015-02-03 5 views
42

मेरे पास एक फ़ंक्शन (foo) है जो एक और फ़ंक्शन (bar) कहता है। यदि bar() का आविष्कार HttpError उठाता है, तो मैं इसे विशेष रूप से संभालना चाहता हूं यदि स्थिति कोड 404 है, अन्यथा फिर से उठाएं।ब्लॉक को छोड़कर एक अपवाद बढ़ाने के लिए एक समारोह को मजाक करना

मैं इस foo फ़ंक्शन के आसपास कुछ यूनिट परीक्षण लिखने की कोशिश कर रहा हूं, bar() पर कॉल का मज़ाक उड़ा रहा हूं। दुर्भाग्यवश, मैं अपने except ब्लॉक द्वारा पकड़ा गया अपवाद बढ़ाने के लिए bar() पर नकली कॉल प्राप्त करने में असमर्थ हूं।

import unittest 
import mock 
from apiclient.errors import HttpError 


class FooTests(unittest.TestCase): 
    @mock.patch('my_tests.bar') 
    def test_foo_shouldReturnResultOfBar_whenBarSucceeds(self, barMock): 
     barMock.return_value = True 
     result = foo() 
     self.assertTrue(result) # passes 

    @mock.patch('my_tests.bar') 
    def test_foo_shouldReturnNone_whenBarRaiseHttpError404(self, barMock): 
     barMock.side_effect = HttpError(mock.Mock(return_value={'status': 404}), 'not found') 
     result = foo() 
     self.assertIsNone(result) # fails, test raises HttpError 

    @mock.patch('my_tests.bar') 
    def test_foo_shouldRaiseHttpError_whenBarRaiseHttpErrorNot404(self, barMock): 
     barMock.side_effect = HttpError(mock.Mock(return_value={'status': 500}), 'error') 
     with self.assertRaises(HttpError): # passes 
      foo() 

def foo(): 
    try: 
     result = bar() 
     return result 
    except HttpError as error: 
     if error.resp.status == 404: 
      print '404 - %s' % error.message 
      return None 
     raise 

def bar(): 
    raise NotImplementedError() 

मैं Mock docs जो कहते हैं कि तुम मज़ाक उड़ाया समारोह त्रुटि जुटाने के लिए एक Exception वर्ग के लिए एक Mock उदाहरण के side_effect स्थापित करना चाहिए पीछा किया:

यहाँ मेरी कोड है जो मेरी समस्या को दिखाता है।

मैंने कुछ अन्य संबंधित स्टैक ओवरफ्लो क्यू & पर भी देखा, और ऐसा लगता है कि मैं वही कर रहा हूं जो वे कर रहे हैं और उनके नकली द्वारा अपवाद को उठाया जा रहा है।

क्यों barMock की side_effect स्थापित कर रही है के कारण उठाया होने की उम्मीद Exception नहीं? अगर मैं कुछ अजीब कर रहा हूं, तो मुझे अपने except ब्लॉक में तर्क परीक्षण के बारे में कैसे जाना चाहिए?

+0

मुझे पूरा यकीन है कि आपका अपवाद * उठाया जा रहा है, लेकिन मुझे यकीन नहीं है कि आप वहां 'resp.status' कोड कैसे सेट कर रहे हैं। 'HTTPError' कहां से आता है? –

+0

@MartijnPieters 'HttpError' एक वर्ग है जिसे [Google की' apiclient' lib] (https://developers.google.com/api-client-library/python/) में परिभाषित किया गया है जिसे हम GAE में उपयोग करते हैं। यह '__init__' को पैरा' (रेस, कंटेंट) 'के साथ परिभाषित किया गया है, इसलिए मैं निर्दिष्ट स्थिति कोड के साथ प्रतिक्रिया के लिए एक नकली उदाहरण बनाने का प्रयास कर रहा था। –

+0

ठीक है, तो यह [इस वर्ग] है (https://github.com/google/google-api-python-client/blob/master/googleapiclient/errors.py#L35-L63); लेकिन आपको उपयोगकर्ता को 'return_value' की आवश्यकता नहीं है; 'resp' को * नहीं कहा जा रहा है *। –

उत्तर

54

आपका नकली अपवाद को ठीक से बढ़ा रहा है, लेकिन error.resp.status मान गुम है। बल्कि उपयोग return_value से, बस Mock बताया कि status एक विशेषता है:

barMock.side_effect = HttpError(mock.Mock(status=404), 'not found') 

Mock() को अतिरिक्त कीवर्ड तर्क जिसके परिणामस्वरूप वस्तु पर विशेषताओं के रूप में स्थापित कर रहे हैं।

मैं एक my_tests मॉड्यूल में अपने foo और bar परिभाषाएँ शब्दों में कहें, तो मैं यह भी इस्तेमाल कर सकते हैं HttpError class में जोड़ा और अपनी परीक्षा तो सफलता के लिए दौड़ा जा सकता है:

>>> from my_tests import foo, HttpError 
>>> import mock 
>>> with mock.patch('my_tests.bar') as barMock: 
...  barMock.side_effect = HttpError(mock.Mock(status=404), 'not found') 
...  result = my_test.foo() 
... 
404 - 
>>> result is None 
True 

तुम भी print '404 - %s' % error.message देख सकते हैं लाइन रन, लेकिन मुझे लगता है कि आप वहां error.content का उपयोग करना चाहते थे; यह किसी भी दर पर दूसरी तर्क से HttpError() विशेषता है।

+0

यह चाल है, धन्यवाद! –

संबंधित मुद्दे