পাইথন একাধিক রিটার্ন মানগুলিকে উপহাস করে


168

আমি পাইথনস মক.প্যাচ ব্যবহার করছি এবং প্রতিটি কলের ফিরতি মান পরিবর্তন করতে চাই। এখানে সতর্কতা: প্যাচ করা হচ্ছে ফাংশনটির কোনও ইনপুট নেই, তাই ইনপুটটির ভিত্তিতে আমি ফেরতের মানটি পরিবর্তন করতে পারি না।

রেফারেন্সের জন্য আমার কোড এখানে।

def get_boolean_response():
    response = io.prompt('y/n').lower()
    while response not in ('y', 'n', 'yes', 'no'):
        io.echo('Not a valid input. Try again'])
        response = io.prompt('y/n').lower()

    return response in ('y', 'yes')

আমার পরীক্ষার কোড:

@mock.patch('io')
def test_get_boolean_response(self, mock_io):
    #setup
    mock_io.prompt.return_value = ['x','y']
    result = operations.get_boolean_response()

    #test
    self.assertTrue(result)
    self.assertEqual(mock_io.prompt.call_count, 2)

io.prompt"ইনপুট" এর কেবলমাত্র একটি প্ল্যাটফর্ম স্বাধীন (অজগর 2 এবং 3) সংস্করণ। সুতরাং শেষ পর্যন্ত আমি ব্যবহারকারীদের ইনপুট উপহাস করার চেষ্টা করছি। আমি রিটার্ন মানটির জন্য একটি তালিকা ব্যবহার করার চেষ্টা করেছি, তবে এটি কাজ করে না।

আপনি দেখতে পাচ্ছেন যে যদি ফেরতের মানটি কিছু অবৈধ হয় তবে আমি এখানে একটি অসীম লুপ পাব। সুতরাং আমার শেষ পর্যন্ত রিটার্ন মান পরিবর্তন করার একটি উপায় প্রয়োজন, যাতে আমার পরীক্ষাটি শেষ হয়।

(এই প্রশ্নের উত্তর দেওয়ার আরেকটি সম্ভাব্য উপায় হ'ল আমি ব্যাখ্যা করতে পারি যে কীভাবে আমি ইউনিট-পরীক্ষায় ব্যবহারকারীদের ইনপুটটি নকল করতে পারি)


এর কোনও DUP এই প্রশ্নের প্রধানত কারণ আমি ইনপুট তারতম্য ক্ষমতা হবে না।

উপর উত্তর মন্তব্য এক এই প্রশ্নের একই লাইন বরাবর, কিন্তু কোন উত্তর / মন্তব্য প্রদান করা হয়েছে।


3
response is not 'y' or 'n' or 'yes' or 'no'মধ্যে না করছেন আপনি কি মনে করেন এটা আছে। দেখুন আমি একাধিক মানের বিপরীতে একটি পরিবর্তনশীল কীভাবে পরীক্ষা করব? এবং আপনি উচিত না ব্যবহার isস্ট্রিং মান, ব্যবহার তুলনা ==তুলনা মান বস্তু নয় পরিচয়।
মার্টিজন পিটারস

এখানেও সাবধানতা অবলম্বন করুন। দেখে মনে হচ্ছে আপনি isস্ট্রিং আক্ষরিক তুলনা করতে ব্যবহার করার চেষ্টা করছেন । এটা করবেন না। এটি (কখনও কখনও) কাজ করে এমন ঘটনাটি সিপিথনে কেবল একটি বাস্তবায়ন বিশদ। এছাড়াও, response is not 'y' or 'n' or 'yes' or 'no'সম্ভবত আপনি যা ভাবেন তা করছেন না ...
ম্যাগসিলসন

উত্তর:


300

আপনি একটি ধার্য করতে পারেন iterable করতে side_effectএবং মক ক্রমানুসারে প্রতিটি সময় এটা বলা হয় আগামী মান হবে:

>>> from unittest.mock import Mock
>>> m = Mock()
>>> m.side_effect = ['foo', 'bar', 'baz']
>>> m()
'foo'
>>> m()
'bar'
>>> m()
'baz'

Mock()ডকুমেন্টেশন উদ্ধৃত :

তাহলে side_effect একটি iterable তাহলে উপহাস প্রতিটি কলের iterable থেকে পরবর্তী মান ফিরে আসবে।

অন্যদিকে, পরীক্ষা কার্যকর response is not 'y' or 'n' or 'yes' or 'no'হবে না ; যদি আপনি অভিব্যক্তি জিজ্ঞাসা করা হয় (response is not 'y')true থাকে বা 'y'TRUE (সবসময় মামলা, একটি খালি স্ট্রিং সবসময় সত্য), ইত্যাদি হয় উভয় দিকে বিভিন্ন এক্সপ্রেশন orঅপারেটার হয় স্বাধীন । দেখুন আমি একাধিক মানের বিপরীতে একটি পরিবর্তনশীল কীভাবে পরীক্ষা করব?

আপনি উচিত এছাড়াও ব্যবহার করবেন isএকটি স্ট্রিং বিরুদ্ধে পরীক্ষা করা হবে। সিপিথন ইন্টারপ্রেটার নির্দিষ্ট কিছু পরিস্থিতিতে স্ট্রিং অবজেক্টগুলিকে পুনরায় ব্যবহার করতে পারে তবে এটি এমন আচরণ নয় যা আপনার উপর নির্ভর করা উচিত।

যেমন ব্যবহার করুন:

response not in ('y', 'n', 'yes', 'no')

পরিবর্তে; এটি একই বিষয়বস্তু (মান) সহ একটি স্ট্রিংয়ের উল্লেখ করে কিনা তা নির্ধারণের জন্য সমতা পরীক্ষা ( ==) ব্যবহার করবে response

একই প্রযোজ্য response == 'y' or 'yes'; response in ('y', 'yes')পরিবর্তে ব্যবহার করুন।


মানক দিয়ে এটি করার কোনও উপায় আছে mock? আমি যেমন স্ট্যান্ডার্ড মক দিয়ে যাচ্ছি তখন কি ম্যাজিকমকের সাথে প্যাচ ব্যবহার করার কোনও উপায় আছে?
নিক হামিউরিচ

@ হামডিনগার: এটি স্টারার্ড Mockক্লাসের একটি বৈশিষ্ট্য ।
মার্টিজন পিটারস

17
একটি তালিকা বরাদ্দ করা কেবল অজগর 3 এর সাথে কাজ করে বলে মনে হচ্ছে। পাইথন ২.7 দিয়ে পরীক্ষা করা আমার পরিবর্তে ( m.side_effect = iter(['foo', 'bar', 'baz'])) ব্যবহার করতে হবে to
ব্যবহারকারী 686249

1
@ ব্যবহারকারী 6866৪৪৯: আমি প্রকৃতপক্ষে এটি পুনরুত্পাদন করতে পারি, কারণ একটি পদ্ধতি থেকে নির্দিষ্টকরণ একটি lambda(ফাংশন) উত্পাদন করে, একটি নয় MagicMock। একটি ফাংশন বস্তুর করতে পারবে না আছে , বৈশিষ্ট্য, যাতে side_effectঅ্যাট্রিবিউট হয়েছে একটি iterable যাবে। আপনার যদিও পদ্ধতিটি নির্দিষ্ট করা উচিত নয়। আরও ভাল ব্যবহার mock.patch.object(requests.Session, 'post'); ফলস্বরূপ এমন কোনও প্যাচার অবজেক্টে যা পদ্ধতিতে যথাযথভাবে অটো-স্পেস করে এবংside_effect সঠিকভাবে সমর্থন করে ।
মার্টিজন পিটারস

3
@ জোমজর 2: পুনরাবৃত্তিটি শেষ হয়ে গেলে StopIterationউত্থাপিত হয়। আপনি যে কোনও পুনরাবৃত্তকারী ব্যবহার করতে পারেন, তাই আপনি একবার itertools.chain(['Foo'], itertools.repeat('Bar'))উত্পাদন করতে ব্যবহার করতে পারেন Foo, তারপরে চিরকালের জন্য উত্পাদন করুন Bar
মার্টিজন পিটারস
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.