Sahte ve MagicMock


138

Benim anlayışım MagicMock otomatik olarak "sihirli yöntemler" yapar böylece listeler, yinelemeler ve benzeri sorunsuz bir şekilde destek sağlayan Mock bir süper set olduğunu ... O zaman düz Mock var nedeni nedir? Bu sadece pratik olarak göz ardı edilebilecek MagicMock'un soyulmuş bir versiyonu değil mi? Mu Mock sınıf bulunmayan herhangi numara biliyor MagicMock ?

Yanıtlar:


99

Sade Mock'un mevcut olmasının nedeni nedir ?

Mock'un yazarı Michael Foord, Pycon 2011'de (31:00) çok benzer bir soru sordu :

S: MagicMock, yeteneği varsayılan sahte nesneye katlamak yerine neden ayrı bir şey yaptı?

C: Makul bir cevap, MagicMock'un çalışma şeklinin, tüm Mock'ları oluşturarak ve bunları ayarlayarak tüm bu protokol yöntemlerini önceden yapılandırmasıdır, bu nedenle her yeni alay bir sürü yeni alay oluşturduğunda ve bunları protokol yöntemleri olarak ayarlayıp yöntemler bir sürü daha alay yarattı ve protokol yöntemlerine koydu, sonsuz özyinelemeye sahipsin ...

Ya bir konteyner nesnesi olarak alayınıza erişmenin bir hata olmasını istiyorsanız - bunun çalışmasını istemezsiniz? Her alay otomatik olarak her protokol yöntemine sahipse, bunu yapmak çok daha zor hale gelir. Ve ayrıca, MagicMock sizin için bu ön yapılandırmadan bazılarını yapar, uygun olmayan dönüş değerlerini ayarlar, bu yüzden sizin için her şeyi önceden yapılandırılmış ve kullanılabilir olan bu kolaylığa sahip olmanın daha iyi olacağını düşündüm, ancak sıradan bir sahte olabilir ve sadece var olmak istediğiniz sihirli yöntemleri yapılandırın ...

Basit cevap şudur: İstediğiniz davranış buysa MagicMock'u her yerde kullanın.


12
Bence daha iyi bir cevap: Ne yaptığınızı biliyorsanız MagicMock kullanın, aksi takdirde Mock kullanın.
laike9m

56

Mock ile sihirli yöntemleri alay edebilirsiniz, ancak bunları tanımlamanız gerekir. MagicMock'ta "sihirli yöntemlerin çoğunun varsayılan uygulamaları" bulunur. .

Herhangi bir sihirli yöntemi test etmeniz gerekmiyorsa, Mock yeterlidir ve testlerinize çok fazla yabancı şey getirmez. MagicMock çok fazla sihirli yöntemi test etmeniz gerekiyorsa size biraz zaman kazandıracak.


Tabii ki belgeleri zaten okudum. Bu sorumu yanıtlamıyor - MagicMock tam olarak aynı şeyi yaparsa neden düz Mock ile uğraşıyorsunuz? Testlerimde hiçbir yabancı şey görmüyorum - sadece farklı adı kullanın ve hepsi bu. Peki yakalama nerede?
Vladimir Ignatov

39
Testler minimal olmalı ve sahte nesneler minimal olarak işlevsel olmalıdır, böylece tam olarak neyi test ettiğinizden emin olabilirsiniz. MagicMock'u yalnızca daha fazla şey yaptığı için kullanırsanız, ancak tüm bu "daha fazla" test etmediyseniz, varsayılan MagicMock davranışı nedeniyle bir testin başarısız olma riskini alırsınız. Bu başarısızlık, MagicMock'un varsayılanları hakkında sahte olması gereken şeyden daha fazlasını yansıtabilir. Daha da kötüsü, bir testin başarısız olması durumunda başarılı olma riskini taşırsınız . Risk küçüktür, ancak bu gerçekleşirse çok zaman kaybedersiniz.
Sean Redmond

1
Ben düz JS vs Jquery kullanarak gibi düşünüyorum. Tabii, olabilir tüm JS yapmak jQuery kullanmak, ancak bazı durumlarda, sadece çok az alet işin yapılması için gerekli kullanmak istiyorum. Bu vakaların genellikle ya son derece basit ya da son derece karmaşık olduğunu düşünüyorum.
sokulur

49

Başlangıç ​​olarak, MagicMockbir alt sınıfıdır Mock.

class MagicMock(MagicMixin, Mock)

Sonuç olarak, MagicMock, Mock'un sağladığı her şeyi ve daha fazlasını sağlar. Mock'u MagicMock'un soyulmuş bir versiyonu olarak düşünmek yerine, MagicMock'u Mock'un genişletilmiş bir versiyonu olarak düşünün. Bu, Mock'un neden var olduğu ve Mock'in MagicMock'un üstünde ne sağladığı hakkında sorularınızı ele almalıdır.

İkincisi, MagicMock birçok / en sihirli yöntemin varsayılan uygulamalarını sağlarken Mock sunmaz. Sağlanan sihirli yöntemler hakkında daha fazla bilgi için buraya bakın .

Sağlanan sihirli yöntemlere bazı örnekler:

>>> int(Mock())
TypeError: int() argument must be a string or a number, not 'Mock'
>>> int(MagicMock())
1
>>> len(Mock())
TypeError: object of type 'Mock' has no len()
>>> len(MagicMock())
0

Ve bu kadar sezgisel olmayabilir (en azından benim için sezgisel değil):

>>> with MagicMock():
...     print 'hello world'
...
hello world
>>> MagicMock()[1]
<MagicMock name='mock.__getitem__()' id='4385349968'>

Bu yöntemler ilk kez çağrıldığından MagicMock'a eklenen yöntemleri "görebilirsiniz":

>>> magic1 = MagicMock()
>>> dir(magic1)
['assert_any_call', 'assert_called_once_with', ...]
>>> int(magic1)
1
>>> dir(magic1)
['__int__', 'assert_any_call', 'assert_called_once_with', ...]
>>> len(magic1)
0
>>> dir(magic1)
['__int__', '__len__', 'assert_any_call', 'assert_called_once_with', ...]

Peki, neden MagicMock'u her zaman kullanmıyorsunuz?

Size geri dönecek olan soru şudur: Varsayılan sihirli yöntem uygulamalarında iyi misiniz? Örneğin, mocked_object[1]hata yapmamak sorun değil mi? Sihirli yöntem uygulamalarının zaten orada olması nedeniyle istenmeyen sonuçlarla karşılaşır mısınız?

Bu soruların cevabı evet ise, devam edin ve MagicMock'u kullanın. Aksi takdirde, Mock'a sadık kalın.


12

Bu nedir Python resmi belgeler diyor ki:

Bu örneklerin çoğunda Mock ve MagicMock sınıfları birbirinin yerine kullanılabilir. MagicMock daha yetenekli bir sınıf olduğundan, varsayılan olarak kullanmak mantıklı bir sınıftır.


3

Ben basit Mock daha yararlı olabilir başka bir özel durum buldum MagicMock:

In [1]: from unittest.mock import Mock, MagicMock, ANY
In [2]: mock = Mock()
In [3]: magic = MagicMock()
In [4]: mock.foo == ANY
Out[4]: True
In [5]: magic.foo == ANY
Out[5]: False

Karşılaştırma yapmak ANY, örneğin, bir sahte değer kullanılarak bir değerin hesaplandığı iki sözlük arasındaki hemen hemen her anahtarı karşılaştırmak yararlı olabilir.

Bu, aşağıdakileri kullanıyorsanız geçerli olacaktır Mock:


self.assertDictEqual(my_dict, {
  'hello': 'world',
  'another': ANY
})

bir zam olurken AssertionErrorkullandığınız takdirdeMagicMock

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.