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.