2015-10-26 10 views
7

पायथन मेरे लिए अपेक्षाकृत नई भाषा है। यूनिट परीक्षण और निर्भरता इंजेक्शन कुछ ऐसा है जो मैं थोड़ी देर के लिए कर रहा हूं, इसलिए मैं इसे सी # परिप्रेक्ष्य से परिचित हूं।पायथन में मूल निर्भरता इंजेक्शन (मॉकिंग/परीक्षण उद्देश्यों के लिए)

हाल ही में, मैं पायथन कोड के इस टुकड़े लिखा है:

import requests # my dependency: http://docs.python-requests.org/en/latest/ 

class someClass: 
    def __init__(self): 
     pass 

    def __do(self, url, datagram): 
     return requests.post(self, url, datagram) 

और फिर मुझे एहसास हुआ कि मैं सिर्फ एक हार्ड-कोडेड निर्भरता बनाया था। Bleh।

मुझे क्या करना मेरे कोड को बदलने पर विचार किया था "निर्माता" निर्भरता इंजेक्शन:

def __init__(self,requestLib=requests): 
    self.__request = requestLib 

def __do(self, url, datagram): 
    return self.__request.post(self, url, datagram) 

यह अब मुझे यूनिट टेस्टिंग के लिए एक नकली/नकली निर्भरता इंजेक्षन करने की अनुमति देता है, लेकिन यह अगर यकीन नहीं था पायथन-आईसी माना जाता था। तो मैं मार्गदर्शन के लिए पाइथन समुदाय से अपील कर रहा हूं।

बुनियादी डीआई करने के लिए पाइथन-आईसी तरीकों के कुछ उदाहरण क्या हैं (ज्यादातर यूनिट टेस्ट लिखने के लिए जो मोक्स/नकली का उपयोग करते हैं)? How does @mock.patch know which parameter to use for each mock object?

+2

ध्यान दें कि '__leading_double_underscore' नाम उलझन का आह्वान करता है, और आम तौर पर टालना चाहिए। परीक्षण के तहत मॉड्यूल के लिए इसे इंजेक्ट करने के लिए ['mock'' request'] (https://docs.python.org/3/library/unittest.mock.html) करना आसान नहीं होगा? – jonrsharpe

+0

मैंने पढ़ा कि __leading डबल अंडरस्कोर एक विधि को निजी रूप से चिह्नित करना था। क्या मुझे गलती हुई थी? यदि हां, तो मुझे कुछ निजी कैसे चिह्नित करना चाहिए? – Pretzel

+0

क्या इसे इंजेक्ट करने के बजाय मॉड्यूल के लिए अनुरोधों को मॉक करना आसान होगा? मुझे नहीं पता। मैं चीजों को करने के पाइथन तरीकों से परिचित नहीं हूं, इसलिए मैं पूछ रहा हूं। ;) – Pretzel

उत्तर

5

कि ऐसा मत करो:

परिशिष्ट किसी को भी मॉक जवाब के बारे में उत्सुक के लिए, मैं यहाँ एक अलग सवाल पूछने का फैसला किया। बस सामान्य के रूप में अनुरोध आयात करें और उन्हें सामान्य के रूप में उपयोग करें। अपने रचनाकारों के लिए तर्क के रूप में पुस्तकालयों को पास करना एक मजेदार बात है, लेकिन आपके उद्देश्यों के लिए बहुत ही पागल और अनावश्यक नहीं है। यूनिट परीक्षणों में चीजों को नकल करने के लिए, नकली पुस्तकालय का उपयोग करें। अजगर 3 में यह मानक पुस्तकालय में बनाया गया है

https://docs.python.org/3.4/library/unittest.mock.html

और अजगर 2 में आप इसे अलग से स्थापित करने के लिए

https://pypi.python.org/pypi/mock

आपका परीक्षण कोड कुछ इस तरह दिखेगा (अजगर 3 का उपयोग की जरूरत है संस्करण)

from unittest import TestCase 
from unittest.mock import patch 

class MyTest(TestCase): 
    @patch("mymodule.requests.post") 
    def test_my_code(self, mock_post): 
     # ... do my thing here... 
+2

तो मैं आपके कोड को पार्स करने की कोशिश कर रहा हूं। '@patch ("mymodule.requests") क्या करता है? और आप "test_my_code" विधि में "अनुरोध" में क्यों गुजर रहे हैं। इसके अलावा, "request.post" के लिए नकली क्या दिखता है? – Pretzel

+1

पैच सजावट प्रतिस्थापन आपके कोड में एक नकली के लिए मॉड्यूल अनुरोध करता है। मेरा कोड सबसे अधिक गलत है, आपको इसे काम करने के लिए अलग-अलग अनुरोधों में प्रत्येक फ़ंक्शन को पैच करना होगा। पैच किए गए फ़ंक्शन को परीक्षण के लिए तर्क के रूप में पारित किया जाता है, ताकि आप इसके खिलाफ जोर दे सकें। अपने उपयोग पर अधिक जानकारी के लिए unittest और नकली के लिए दस्तावेज़ पढ़ें। –

+0

सहायता के लिए धन्यवाद। मैंने आपको चेक मार्क दिया। :) – Pretzel

0

अनुरोध मॉड्यूल इंजेक्शन करते समय थोड़ा अधिक हो सकता है, यह एक बहुत अच्छा पी है इंजेक्शन के रूप में कुछ निर्भरताओं के लिए ractice।

यह मामला हो सकता है कि एक पूर्ण रूप से ढांचा सिर्फ वही है जो आपको चाहिए। इसके लिए वहां उत्कृष्ट मॉड्यूल हैं जैसे Injector

एक और अधिक न्यूनतम और सीधे आगे दृष्टिकोण आपके लिए नौकरी करने के लिए एक सजावटी का उपयोग करना होगा। out there के लिए कुछ मॉड्यूल हैं।

मैं इस तरह के एक मॉड्यूल को बनाए रखता हूं: Injectable, जो पाइथन 3 @autowired सजावट प्रदान करता है ताकि आसान और साफ निर्भरता इंजेक्शन सक्षम हो सके।स्पष्ट रूप से पारित करने में सक्षम है प्रारंभ

  • समारोह सभी
  • निर्भरता पर autowiring के बारे में पता होना करने के लिए आलसी हो सकता है नहीं है
  • कॉलर:

    इस डेकोरेटर का मुख्य बिंदु है कि कर रहे हैं निर्भरता उदाहरणों अगर वांछित

मूल रूप से आप इस तरह कोड बारी:

def __init__(self, *, model: Model = None, service: Service = None): 
    if model is None: 
     model = Model() 

    if service is None: 
     service = Service() 

    self.model = model 
    self.service = service 
    # actual code 

इस में:

@autowired 
def __init__(self, *, model: Model, service: Service): 
    self.model = model 
    self.service = service 
    # actual code 

कोई जटिल सामान, कोई सेटअप, कोई वर्कफ़्लो लागू किया।

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