2013-04-21 21 views
46

İçe aktarılan bir modülden @patch işlevinin nasıl kullanılacağını anlamak istiyorum.Python İçe aktarılan bir modülden bir işlevi atama

Buraya kadar uzak olduğum yer.

uygulama/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() 

uygulama/my_module/__ init__.py: mock-test.py

def get_user_name(): 
    return "Unmocked User" 

testi /:

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() 

Bu, beklediğim gibi çalışmaz. "Yamalı" modül sadece get_user_name'un taşınmamış değerini döndürür. Test ettiğim bir ad alanına içe aktardığım diğer paketlerden nasıl yöntemleri alayım?

+1

soru "alay en iyi uygulamalar" konusunda veya ne yaptığınızı mantıklı olsun veya olmasın mı? İlk olarak ['Mock'] (http://www.voidspace.org.uk/python/mock/) gibi alaycı bir kütüphane kullanmayı tercih ediyorum. .mock'] (http://docs.python.org/dev/library/unittest.mock). – Bakuriu

+0

Bu hakkın olup olmadığını soruyorum. Mock'a baktım ama bu problemi çözmenin bir yolunu görmüyorum. Yukarıda Mock'ta yaptığım şeyi yeniden yaratmanın bir yolu var mı? – nsfyn55

cevap

66

Eğer unittest.mock paketinden patch dekoratör kullandığınız modül sizi test app.mocking.get_user_name altında ad bunu yama (bu durumda app.my_module.get_user_name olarak) ithal edilir ad yama değil bulunmaktadır.

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') 

standart kütüphane dokümantasyon bu açıklayan yararlı bir section içerir: Mock aşağıda gibi bir şey denemek ile

yukarıdaki yapmak için.

+0

bu benim sorunuma geliyor. get_user_name, 'test_method'dan farklı bir modülde. Sub_module'de bir şeyle uğraşmanın bir yolu var mı? Onu aşağıda çirkin bir şekilde çözdüm. – nsfyn55

+4

Bu işlev, 'app.mocking' içine aynı ad alanında bulunduğundan 'get_user_name' 'test_method' yerine farklı bir modülde olması önemli değil. –

+0

var. Evet, teşekkürler! – nsfyn55

5

Matti John'un cevabı, sorununuzu çözerken (ve bana da yardımcı oldu, teşekkürler!), Ancak orijinal 'get_user_name' işlevinin yerine atandığı yeri taklit etmenizi öneririm. Bu, işlevin ne zaman değiştirildiğini ve ne zaman yapıldığını kontrol etmenizi sağlar. Ayrıca, bu aynı testte birkaç değişiklik yapmanıza izin verecektir. Bunu yapmak için, oldukça simillar şekilde statment 'ile' kullanın:

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') 
+0

'u saplamanız yeterlidir. Bu, sorulan soruya göre bir anlam ifade etmiyor. Bir dekoratör veya içerik yöneticisi olarak 'patch 'kullanmanız, kullanım durumuna özgüdür. Örneğin, 'xunit' veya' pytest' sınıfındaki tüm testler için bir değere atama yapmak için 'patch'ı bir dekoratör olarak kullanabilirken, diğer durumlarda bağlam yöneticisi tarafından sağlanan ince taneli kontrole sahip olmak yararlı olur. – nsfyn55

İlgili konular