একটি শ্রেণি উপহাস করা: মক () বা প্যাচ ()?


116

আমি পাইথনের সাথে মক ব্যবহার করছি এবং ভাবছিলাম যে এই দুটি পদ্ধতির মধ্যে কোনটি ভাল (পড়ুন: আরও অজগর)।

একটি পদ্ধতি : কেবল একটি মক অবজেক্ট তৈরি করুন এবং এটি ব্যবহার করুন। কোডটি দেখে মনে হচ্ছে:

def test_one (self):
    mock = Mock()
    mock.method.return_value = True 
    self.sut.something(mock) # This should called mock.method and checks the result. 
    self.assertTrue(mock.method.called)

পদ্ধতি দুটি : একটি মোক তৈরি করতে প্যাচ ব্যবহার করুন। কোডটি দেখে মনে হচ্ছে:

@patch("MyClass")
def test_two (self, mock):
    instance = mock.return_value
    instance.method.return_value = True
    self.sut.something(instance) # This should called mock.method and checks the result. 
    self.assertTrue(instance.method.called)

দুটি পদ্ধতিই একই কাজ করে। আমি পার্থক্য সম্পর্কে অনিশ্চিত।

কেউ কি আমাকে আলোকিত করতে পারে?


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

2
@ মিশেলব্রান্নান: আপনার মন্তব্যের জন্য আপনাকে ধন্যবাদ। এটি সত্যই কার্যকর।
সারদাথ্রিয়ন - এসই এর বিরুদ্ধে

উত্তর:


151

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

>>> class MyClass(object):
...   def __init__(self):
...     print 'Created MyClass@{0}'.format(id(self))
... 
>>> def create_instance():
...   return MyClass()
... 
>>> x = create_instance()
Created MyClass@4299548304
>>> 
>>> @mock.patch('__main__.MyClass')
... def create_instance2(MyClass):
...   MyClass.return_value = 'foo'
...   return create_instance()
... 
>>> i = create_instance2()
>>> i
'foo'
>>> def create_instance():
...   print MyClass
...   return MyClass()
...
>>> create_instance2()
<mock.Mock object at 0x100505d90>
'foo'
>>> create_instance()
<class '__main__.MyClass'>
Created MyClass@4300234128
<__main__.MyClass object at 0x100505d90>

patchএমন MyClassএকটি জায়গায় প্রতিস্থাপন করে যা আপনাকে কল করে এমন ফাংশনগুলিতে শ্রেণীর ব্যবহার নিয়ন্ত্রণ করতে দেয়। আপনি একবার কোনও ক্লাস প্যাচ করলে, ক্লাসের উল্লেখগুলি মক দৃষ্টান্ত দ্বারা সম্পূর্ণ প্রতিস্থাপন করা হয়।

mock.patchসাধারণত আপনি যখন এমন কোনও কিছু পরীক্ষা করে যা পরীক্ষার অভ্যন্তরে কোনও শ্রেণির একটি নতুন উদাহরণ তৈরি করে used mock.Mockউদাহরণগুলি আরও পরিষ্কার এবং পছন্দসই। যদি আপনার self.sut.somethingপদ্ধতিটি MyClassপরামিতি হিসাবে কোনও উদাহরণ পাওয়ার পরিবর্তে কোনও উদাহরণ তৈরি করে , তবে mock.patchএখানে উপযুক্ত হবে।


2
@ ডি.শ্যাওলি কীভাবে আমরা অন্য শ্রেণীর ভিতরে ইনস্ট্যান্টেড ক্লাসে প্যাচ করব যা পরীক্ষার অধীনে থাকা দরকার।
রবি 404

4
@ আরভজ - " হ্যাচ টু প্যাচ" একটি পঠন দিন। সঠিকভাবে কাজ করা এটি অন্যতম কঠিন বিষয়।
ডি.শ্যাওলি

আমার উপহাস পরীক্ষা অনুরূপ পদ্ধতি দুই । আমি চাই মাইক্লাস উদাহরণটি একটি ব্যতিক্রম বাড়িয়ে তুলুক। আমি mock.side_effect এবং mock.return_value.side_effect এবং তাদের কাজ করেনি উভয়ই চেষ্টা করেছি। আমি কি করব?
হুসেন

5
@ ডি.শোলে লিঙ্কটি নষ্ট হয়ে গেছে, এটি এখনই এখানে পাওয়া যাবে: "
হ্যাচ টু টু

2
একটি প্যাচ বর্গ বস্তুর দেখুন stackoverflow.com/questions/8469680/...
storm_m2138

27

আমি এটিতে একটি ইউটিউব ভিডিও পেয়েছি ।

সংক্ষিপ্ত উত্তর: mockআপনি যে বিষয়টিকে ঠাট্টা করতে চান তা যখন পাস করছেন এবং যখন আপনি না হন তখন ব্যবহার করুন patch। দুটির মধ্যে মক দৃ strongly়ভাবে পছন্দ করা হয় কারণ এর অর্থ আপনি সঠিক নির্ভরতা ইনজেকশন সহ কোড লিখছেন।

নির্বোধ উদাহরণ:

# Use a mock to test this.
my_custom_tweeter(twitter_api, sentence):
    sentence.replace('cks','x')   # We're cool and hip.
    twitter_api.send(sentence)

# Use a patch to mock out twitter_api. You have to patch the Twitter() module/class 
# and have it return a mock. Much uglier, but sometimes necessary.
my_badly_written_tweeter(sentence):
    twitter_api = Twitter(user="XXX", password="YYY")
    sentence.replace('cks','x') 
    twitter_api.send(sentence)
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.