Python, return_value yerine MagicMock nesnesini döndürür


93

a.pyİki sınıf içeren bir python dosyam var Ave B.

class A(object):
    def method_a(self):
        return "Class A method a"

class B(object):
    def method_b(self):
        a = A()
        print a.method_a()

Ben unittest istiyorum method_bsınıfta Balay ile A. İşte testa.pybu amaç için dosyanın içeriği :

import unittest
import mock
import a


class TestB(unittest.TestCase):

    @mock.patch('a.A')
    def test_method_b(self, mock_a):
        mock_a.method_a.return_value = 'Mocked A'
        b = a.B()
        b.method_b()


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

Çıktıya girmeyi bekliyorum Mocked A. Ama aldığım şey:

<MagicMock name='A().method_a()' id='4326621392'>

Nerede yanlış yapıyorum


1
Test ederken , sınıfın bir örneği olmayan from ( başka bir şey belirtmediğiniz için normal) A()döndürür . Bunu tanımlanmış bir şey olarak ayarlamanız gerekir . return_valuemock_AMagicMockAreturn_valuemethod_a
— jonrsharpe

3
mock_a.method_a.return_value = 'Mocked A' => mock_a (). method_a.return_value = 'Mocked A' daha iyi olmalı :)
— Ali SAID OMAR

@AliSAIDOMAR tam olarak doğru, mock_ametoda sahip olması gereken çağrının dönüş değeri , mock_akendisine değil .
— jonrsharpe

1
@jonrsharpe. Açıklaman için teşekkürler. Ben sadece denedim. Hem mock_a().method_a.return_value = 'Mocked A've mock_a.return_value.method_a.return_value = 'Mocked A'çalıştı. Yorumlarınız için çok teşekkürler. Lütfen devam edip bir cevap olarak sorar mısınız?
— Mehdi Jafarnia Jahromi

@MehdiJafarniaJahromi çok teşekkürler!
— Niakros

Yanıtlar:


104

Siz @mock.patch('a.A'), Atest edilen koddaki sınıfı ile değiştiriyorsunuz mock_a.

In B.method_bsize daha sonra ayarlamak a = A()şimdi hangi a = mock_a()- yani aolduğu return_valuebir mock_a. Bu değeri belirtmediğiniz için normaldir MagicMock; bu da yapılandırılmamıştır, bu nedenle MagicMocküzerinde yöntemler çağırırken varsayılan yanıtı (yine başka bir ) alırsınız .

Bunun yerine, yapılandırmak istediğiniz bir ya kadar yapabilirsiniz uygun yöntemi, sahip olmak:return_valuemock_a

mock_a().method_a.return_value = 'Mocked A' 
    # ^ note parentheses

veya belki daha açık bir şekilde:

mock_a.return_value.method_a.return_value = 'Mocked A'

Kodunuz a = A, o a.method_a()zaman sahte yönteminizi tetikleyeceği gibi durumda (sınıf atamak, bir örnek oluşturmak değil) işe yarardı.


4
Harika. Günümü gün ettin.
— Vishal

@Jonrsharpe Merhaba, ben bir pandalar dataframe kullanıyorum df.columns benim kontrol etmek eğer koşul. Parantezleri kullanmaz (yani çağrılabilir değildir). Bu durumda bir listeyi döndürmek için ne yapmalıyım? Teşekkürler!
— imsrgadich

@imsrgadich bunun için bir alaya ihtiyacın var mı? Sadece uygun veri çerçevesini oluşturun, bunu bir test değeri olarak değerlendirin.
— jonrsharpe

@jonrsharpe evet, bunu yapabilirim ama aynı zamanda çağrılan yöntemimde df.drop yapıyorum ve bunun üzerine veri çerçevesini çağrılan yöntemden geri döndürmüyorum. Bu bir sorun yaratır. Bunu mock_data.configure_mock(columns='my_column')çözen bir yol buldum . Yine de cevap için teşekkürler. (ref: bradmontgomery.net/blog/how-world-do-you-mock-name-attribute )
— imsrgadich

Aynı testte iki SQLAlchemy modeliyle dalga geçtiğinizde bu işe yaramıyor gibi görünüyor. İlki iyi çalışıyor, ancak ikincisi ne tanımladığınızdan bağımsız olarak bir MagicMock döndürecektir.
— Juha Untinen
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.