পাইথন আমদানি করা মডিউল থেকে একটি ফাংশন উপহাস করছে


125

আমি কীভাবে @patchআমদানি করা মডিউল থেকে কোনও ফাংশন করব তা বুঝতে চাই ।

এই যে আমি এখন পর্যন্ত আছি।

অ্যাপ্লিকেশন / mocking.py:

from app.my_module import get_user_name

def test_method():
  return get_user_name()

if __name__ == "__main__":
  print "Starting Program..."
  test_method()

অ্যাপ্লিকেশন / my_module / __ init__.py:

def get_user_name():
  return "Unmocked User"

পরীক্ষা / mock-test.py:

import unittest
from app.mocking import test_method 

def mock_get_user():
  return "Mocked This Silly"

@patch('app.my_module.get_user_name')
class MockingTestTestCase(unittest.TestCase):

  def test_mock_stubs(self, mock_method):
    mock_method.return_value = 'Mocked This Silly')
    ret = test_method()
    self.assertEqual(ret, 'Mocked This Silly')

if __name__ == '__main__':
  unittest.main()

আমি আশা করব এটি কাজ করে না । "প্যাচড" মডিউলটি কেবল আনমকড মানটি প্রদান করে get_user_name। আমি অন্যান্য প্যাকেজগুলি যে পদ্ধতিতে পরীক্ষার অধীনে একটি নেমস্পেসে আমদানি করছি তা থেকে কীভাবে উপহাস করব?


1
প্রশ্নটি "সেরা অনুশীলনকে ঠাট্টা করা সম্পর্কে" বা আপনি যা করছেন তা বোঝা যায় কি না? প্রথমটি সম্পর্কে আমি একটি Mockমশকরা গ্রন্থাগার ব্যবহার করতে বলতে চাই , যা পাইথন 3.3 + হিসাবে অন্তর্ভুক্ত রয়েছে unittest.mock
বাকুরিউ

আমি জিজ্ঞাসা করছি আমি এই অধিকার সম্পর্কে যাচ্ছি কিনা? আমি মকের দিকে তাকালাম, তবে এই বিশেষ সমস্যাটি সমাধানের উপায় আমি দেখতে পাচ্ছি না। মোক উপরে আমি যা করেছি তা পুনরায় বিনোদনের কোনও উপায় আছে?
nsfyn55

উত্তর:


167

আপনি যখন প্যাকেজটি patchথেকে ডেকরেটার ব্যবহার করছেন unittest.mockআপনি নামস্থান প্যাচ করছেন না মডিউলটি আমদানি করা হবে (এই ক্ষেত্রে app.my_module.get_user_name) আপনি পরীক্ষার অধীনে নামস্থানে এটি প্যাচ করছেন app.mocking.get_user_name

সাথে উপরে কাজের জন্য Mockনিচের মত করে দেখুন কিছু:

from mock import patch
from app.mocking import test_method 

class MockingTestTestCase(unittest.TestCase):

    @patch('app.mocking.get_user_name')
    def test_mock_stubs(self, test_patch):
        test_patch.return_value = 'Mocked This Silly'
        ret = test_method()
        self.assertEqual(ret, 'Mocked This Silly')

স্ট্যান্ডার্ড লাইব্রেরি ডকুমেন্টেশনে এটি বর্ণনা করে একটি দরকারী বিভাগ অন্তর্ভুক্ত ।


এটি আমার সমস্যা হয়। get_user_nameএর চেয়ে আলাদা মডিউলে test_method। উপ-মডুলে কিছু উপহাস করার কোনও উপায় আছে কি? আমি নীচে একটি কুরুচিপূর্ণভাবে এটি স্থির।
nsfyn55

6
যেহেতু আপনি ফাংশনটি একই নাম স্থানে রাখছেন সেহেতু get_user_nameভিন্ন মডিউলে এটি কিছু যায় আসে না । test_methodapp.mocking
মট্টি জন

2
টেস্ট_প্যাচটি কোথা থেকে এসেছে, এটি ঠিক কী?
মাইক জি

2
টেস্ট_প্যাচটি প্যাচ ডেকোরেটর দ্বারা পাস করা হয় এবং এটি মশকরা get_user_name বস্তু (যেমন ম্যাজিকমোক শ্রেণীর উদাহরণ)। এটির মতো নামকরণ করা থাকলে এটি পরিষ্কার হতে পারে get_user_name_patch
মট্টি জন

আপনি কীভাবে পরীক্ষা_মোহাদকে রেফারেন্স করছেন? এর ফলে ত্রুটি হবে, নেম এরির: বিশ্বব্যাপী নাম 'টেস্ট_মোথডো' সংজ্ঞায়িত হয়নি
আদিত্য ২

12

যদিও মট্টি জনের উত্তরটি আপনার সমস্যার সমাধান করেছে (এবং আমাকেও সাহায্য করেছে, ধন্যবাদ!), তবে আমি বিদ্রূপযুক্তটির সাথে মূল 'get_user_name' ফাংশনটি প্রতিস্থাপনের পরামর্শ দেব। ফাংশনটি প্রতিস্থাপন করা হয় এবং কখন হয় না তা আপনাকে নিয়ন্ত্রণ করতে দেয়। এছাড়াও, এটি আপনাকে একই পরীক্ষায় বেশ কয়েকটি প্রতিস্থাপন করার অনুমতি দেবে। এটি করার জন্য, একটি সুন্দর সিমিলার পদ্ধতিতে 'উইথ' স্ট্যাটমেন্টটি ব্যবহার করুন:

from mock import patch

class MockingTestTestCase(unittest.TestCase):

    def test_mock_stubs(self):
        with patch('app.mocking.get_user_name', return_value = 'Mocked This Silly'):
            ret = test_method()
            self.assertEqual(ret, 'Mocked This Silly')

6
এটি উত্থাপিত প্রশ্নের এক ধরণের নিরবচ্ছিন্ন। আপনি patchডেকোরেটার বা কনটেক্সট ম্যানেজার হিসাবে ব্যবহার করুন কিনা ব্যবহারের ক্ষেত্রে সুনির্দিষ্ট। উদাহরণস্বরূপ আপনি patchএকটি xunitবা pytestশ্রেণীর সমস্ত পরীক্ষার জন্য একটি মানকে বিদ্রূপ করার জন্য ডেকরেটার হিসাবে ব্যবহার করতে পারেন অন্য ক্ষেত্রে ক্ষেত্রে প্রসঙ্গ ব্যবস্থাপকের দ্বারা জরিমানা দানা নিয়ন্ত্রণের জন্য এটি কার্যকর।
nsfyn55
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.