একটি ব্লক ব্যতীত পরীক্ষার জন্য ব্যতিক্রম বাড়ানোর জন্য একটি ক্রিয়াকলাপ ocking


119

আমার একটি ফাংশন রয়েছে ( foo) যা অন্য ফাংশনকে কল করে ( bar)। যদি অনুরোধ করা bar()একটি উত্থাপিত হয় HttpError, তবে আমি স্থিতি কোড 404 হ'ল অন্যথায় পুনরায় বাড়াতে বিশেষভাবে এটি পরিচালনা করতে চাই।

আমি এই fooফাংশনটির আশেপাশে কিছু ইউনিট পরীক্ষা লেখার চেষ্টা করছি , কল করার জন্য মশকরা করছি bar()। দুর্ভাগ্যক্রমে, bar()আমার exceptব্লক ধরা পড়েছে এমন একটি ব্যতিক্রম উত্থাপনের জন্য আমি মশকরা কল পেতে অক্ষম ।

এখানে আমার কোড যা আমার সমস্যার চিত্র তুলে ধরে:

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()

আমি অনুসৃত নকল ডক্স যা বলে যে আপনি সেট করা উচিত side_effectএকটি এর Mockএকটি থেকে উদাহরণস্বরূপ Exceptionব্যঙ্গ ফাংশন বাড়াতে ত্রুটি আছে বর্গ।

আমি অন্য কিছু সম্পর্কিত স্ট্যাকওভারফ্লো প্রশ্নোত্তর হিসাবেও দেখেছি এবং দেখে মনে হচ্ছে যে তারা তাদের মক দ্বারা উত্থাপিত হওয়ার কারণ হিসাবে এবং ব্যতিক্রম করার জন্য তারা করছে একই কাজ করছি।

কেন সেটিং করা হয় side_effectএর barMockপ্রত্যাশিত ঘটাচ্ছে না Exceptionউত্থাপিত হবে? আমি যদি অদ্ভুত কিছু করে থাকি তবে আমার exceptব্লকটিতে যুক্তি পরীক্ষা করার উপায়টি কীভাবে করব ?


আমি প্রায় নিশ্চিত করুন যে আপনার ব্যতিক্রম নই হয় উত্থাপিত হচ্ছে, কিন্তু আমি নিশ্চিত কিভাবে আপনি সেটিং করা হয় নই resp.statusকোড আছে। কোথা HTTPErrorথেকে আসে?
মার্টিজন পিটারস

@MartijnPieters HttpErrorকোন ক্লাসে সংজ্ঞায়িত গুগলের apiclientliberal এর সংক্ষিপ্ত রূপ যা আমরা Gae তাতে ব্যবহার করুন। এটি __init__প্যারামগুলির সাথে সংজ্ঞায়িত করা হয়েছে (resp, content)তাই আমি যথাযথ স্থিতি কোডটি উল্লেখ করে প্রতিক্রিয়ার জন্য একটি মক উদাহরণ তৈরি করার চেষ্টা করছিলাম।
জেসি ওয়েব

ঠিক আছে, তাই এটি এই শ্রেণি ; তবে আপনার return_valueতখন ব্যবহারকারীর দরকার নেই ; বলাresp হচ্ছে না ।
মার্টিজন পিটারস

1
আমি আমার কোডটি ব্যবহার না করে আবার চেষ্টা করেছি HttpErrorএবং পরিবর্তে কেবল একটি নিয়মিত Exceptionউদাহরণ ব্যবহার করার চেষ্টা করেছি । এটি পুরোপুরি কাজ করে। এর অর্থ হ'ল আমি HttpErrorউদাহরণটি কীভাবে কনফিগার করছি তার সাথে অবশ্যই কিছু করার দরকার আছে , সম্ভবত আমি Mockপ্রতিক্রিয়াটির জন্য উদাহরণ তৈরি করছি এর সাথে সম্পর্কিত ।
জেসি ওয়েব

উত্তর:


141

আপনার মোকটি ব্যতিক্রমটিকে ঠিকঠাক করে তুলছে, তবে error.resp.statusমানটি অনুপস্থিত। বরং ব্যবহার তুলনায় return_valueশুধু বলতে Mockযে statusএকটি বৈশিষ্ট্য হল:

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

অতিরিক্ত কীওয়ার্ড যুক্তি Mock() ফলাফল অবজেক্টের বৈশিষ্ট্য হিসাবে সেট করা আছে।

আমি আপনার fooএবং barসংজ্ঞাগুলি একটি my_testsমডিউলে রেখেছি , HttpErrorক্লাসে যুক্ত করেছি যাতে আমিও এটি ব্যবহার করতে পারি এবং আপনার পরীক্ষাটি সাফল্যের দিকে যেতে পারে:

>>> 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()দ্বিতীয় যুক্তি থেকে অ্যাট্রিবিউট সেট করে।


2
side_effectগুরুত্বপূর্ণ অংশ
ড্যানিয়েল বাটলার
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.