2016-07-26 5 views
6

मान लें कि मेरे पास इस तरह की कक्षा है।पायथन यूनिट परीक्षण के लिए नकली कक्षा विधि कैसे आपूर्ति करें?

class SomeProductionProcess(CustomCachedSingleTon): 

     def loaddata(): 
      """ 
      Uses an iterator over a large file in Production for the Data pipeline. 
      """ 

      pass 

अब परीक्षण समय मैं loaddata() विधि के अंदर तर्क बदलना चाहते हैं। यह एक साधारण कस्टम तर्क होगा जो बड़े डेटा को संसाधित नहीं करता है।

हम पाइथन मॉक यूनिटटेस्ट फ्रेमवर्क का उपयोग करके परीक्षण समय पर loaddata() के कस्टम कार्यान्वयन की आपूर्ति कैसे करते हैं?

+0

कृपया ध्यान दें कि loaddata() एक @classmethod है। इसके अलावा मैं इस श्रेणी में किसी अन्य विधि का परीक्षण करने में सक्षम होने के लिए कस्टम लोडडेटा() की आपूर्ति करना चाहता हूं। – user4654

+0

'मॉक विधि' प्रश्न के मुताबिक अधिक सही होगा, क्योंकि जब आप 'क्लास विधि' कहते हैं तो नकली 'क्लासमेथ' का अर्थ होता है। एक विधि हमेशा कक्षा के उदाहरण का हिस्सा होती है और कक्षा वर्ग कक्षा का हिस्सा होता है। इसे सजावटी @classmethod के साथ सही परिवर्तन विधि बनाने और पैरामीटर cls जोड़ने के लिए। – msudder

उत्तर

0

चलें कहते हैं कि तुम awesome.py और उस में नाम के एक मॉड्यूल है, तो आप के लिए किया था:

import time 

class SomeProductionProcess(CustomCachedSingleTon): 

    def loaddata(self): 
     time.sleep(30) # simulating a long running process 
     return 2 

फिर अपने unittest जहां नकली loaddata ऐसा दिखाई दे सकता:

import unittest 

import awesome # your application module 


class TestSomeProductionProcess(unittest.TestCase): 
    """Example of direct monkey patching""" 

    def test_loaddata(self): 
     some_prod_proc = awesome.SomeProductionProcess() 
     some_prod_proc.loaddata = lambda x: 2 # will return 2 every time called 
     output = some_prod_proc.loaddata() 
     expected = 2 

     self.assertEqual(output, expected) 

या यह इस तरह दिख सकता है:

import unittest 
from mock import patch 

import awesome # your application module 

class TestSomeProductionProcess(unittest.TestCase): 
    """Example of using the mock.patch function""" 

    @patch.object(awesome.SomeProductionProcess, 'loaddata') 
    def test_loaddata(self, fake_loaddata): 
     fake_loaddata.return_value = 2 
     some_prod_proc = awesome.SomeProductionProcess() 

     output = some_prod_proc.loaddata() 
     expected = 2 

     self.assertEqual(output, expected) 

अब जब आप अपना परीक्षण चलाते हैं, loaddata उन परीक्षण मामलों के लिए 30 सेकंड नहीं लेते हैं।

+0

आपकी प्रतिक्रिया के लिए बहुत बहुत धन्यवाद। वापसी 2 के बजाय, मैं एक स्टब प्रदान करना चाहता हूं जिसे लागू करने की आवश्यकता है, मैं इसे कैसे करूँगा? lamdba x के बजाय: 2 – user4654

+0

जो भी आप लैम्ब्डा के ':' के दायीं ओर डालते हैं, उसे वापस कर दिया जाएगा। – willnx

+0

मेरे बारे में लैम्ब्डा अभिव्यक्ति को पूरी तरह से कैसे हटाया जा रहा है? और बस इसे एक कस्टम समारोह असाइन करना। इस तरह: some_prod_proc = custom_func()। और मुझे चिंता है कि यह पूरी तरह से परीक्षण वातावरण में नहीं बल्कि कार्य परिभाषा को पूरी तरह से ओवरराइड करेगा। – user4654

4

संरचित वापसी_वर्त के साथ कक्षा विधि को आसानी से नकल करने के लिए, unittest.mock.Mock का उपयोग कर सकते हैं।

from unittest.mock import Mock 

mockObject = SomeProductionProcess 
mockObject.loaddata = Mock(return_value=True) 

संपादित करें:

के बाद से आप एक कस्टम कार्यान्वयन के साथ विधि बाहर नकली करना चाहते हैं, तो आप सिर्फ एक कस्टम नकली विधि वस्तु और बाहर मूल विधि स्वैप परीक्षण कार्यावधि में बना सकते हैं।

def custom_method(*args, **kwargs): 
    # do custom implementation 

SomeProductionProcess.loaddata = custom_method 
+0

मैं वापसी मूल्य की बजाय लोडडाटा विधि का एक कस्टम कार्यान्वयन करना चाहता हूं। – user4654

+0

आप कस्टम कार्यान्वयन के लिए लोडडेटा असाइन कर सकते हैं। मुझे एक सेकंड दें और मैं अपना जवाब अपडेट करूंगा। –

5

यहाँ नकली

import mock 


def new_loaddata(cls, *args, **kwargs): 
    # Your custom testing override 
    return 1 


def test_SomeProductionProcess(): 
    with mock.patch.object(SomeProductionProcess, 'loaddata', new=new_loaddata): 
     obj = SomeProductionProcess() 
     obj.loaddata() # This will call your mock method 

मैं unittest मॉड्यूल के बजाय pytest का उपयोग कर यदि आप कर रहे हैं की सलाह देते हैं का उपयोग कर यह करने के लिए एक आसान तरीका है। यह आपके टेस्ट कोड को बहुत क्लीनर बनाता है और unittest.TestCase -स्टाइल परीक्षणों के साथ आपको प्राप्त होने वाले बॉयलरप्लेट को बहुत कम करता है।

+0

धन्यवाद, तो जिस विधि का आपने उल्लेख किया है, क्या यह सबसे अजीब या pytest के अनुसार है? – user4654

+0

'mock' का उपयोग या तो किया जा सकता है। 'Pytest' या' unittest' का उपयोग करने के बीच का अंतर सिर्फ आपके परीक्षण कार्यों की तरह दिखता है। मेरा उदाहरण 'पायस्टेस्ट' प्रारूप का उपयोग करता है, जहां आप केवल नियमित कार्यों का उपयोग करते हैं और 'assert' कथन' में निर्मित होते हैं। एक 'unittest' परीक्षण कैसा दिखता है) के उदाहरण के लिए @ विल्लेक्स [उत्तर] (http://stackoverflow.com/a/38579804/1547004) पर एक नज़र डालें। –

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