Python 2.7 mock / patch: понимание assert_called_XYZ ()

Я относительно новичок в Python и модульном тестировании на Python. Из мира Java я знаю концепцию насмешки, но она, похоже, сильно отличается от того, что я вижу на Python.

Я нашел это руководство, которое я нашел очень полезным: http://www.voidspace.org.uk/python/mock/index.html

Но, когда я писал свои (несколько более сложные) тесты с издеваемыми зависимостями, я заметил, что поведение страха. Я решил создать сокращенный простой пример, который также не работает, как я ожидаю.

Взгляните на это, результат и мое ожидание, которое я добавил в качестве комментариев:

import unittest from mock import patch, Mock, MagicMock class BasicTest(unittest.TestCase): @patch("StringIO.StringIO") def testSomethingNotWorkingAsExpected(self, StringIOMock): StringIOMock.assert_called_once() # asserts, but why? @patch("StringIO.StringIO") def testSomethingSomehowWorking(self, StringIOMock): # self.instantiateStringIO() # intentionally commented out assert StringIOMock.called # does not assert (leading to failure of this test); as expected. If the above line is not commented, this asserts as expected. def instantiateStringIO(self): import StringIO StringIO.StringIO() 

Почему assert_called_once() утверждает создание StringIO даже если оно еще не было StringIO ? И почему assert ClassMock.called приводит к ожидаемым результатам?

Использование assert not ... для утверждения метода не было вызвано. Я нашел здесь: Утвердить, что функция / метод не вызывается с использованием Mock . Я перевернул эту схему в моем случае, опуская ее.

Где-то я нашел шаблон ClassMock.return_value для ссылки на экземпляр. Но я понимаю это как способ создания экземпляра Mock до того, как он будет вызван, а не как способ доступа к экземпляру, который может быть создан внутренним кодом. Или я ошибаюсь?

Моя среда:

  • Python 2.7.3
  • макет 0,8,8
  • Fedora 19

Наверное, мое понимание фальшивки / исправления неверно. Может ли кто-нибудь объяснить, что делает классный макет и как он работает?

Edit1: Добавлен вывод

… и добавил парафраз в parens, чтобы прокомментировать в testSomethingSomehowWorking

Это результат:

 .F ====================================================================== FAIL: testSomethingSomehowWorking (test_test.BasicTest) ---------------------------------------------------------------------- Traceback (most recent call last): File "/usr/lib/python2.7/site-packages/mock.py", line 1224, in patched return func(*args, **keywargs) File "test_test.py", line 15, in testSomethingSomehowWorking assert StringIOMock.called # does not assert; as expected AssertionError ---------------------------------------------------------------------- Ran 2 tests in 0.001s FAILED (failures=1) 

One Solution collect form web for “Python 2.7 mock / patch: понимание assert_called_XYZ ()”

Метод assert_called_once не существует и не выполняет утверждение. Это ничем не отличается от написания StringIOMock.assert_foo_bar_does_not_exist() или любого другого метода. Библиотека макета не проверяет, действительно ли метод, вызванный макетом, существует.

Если вы используете assert_called_once_with тогда он терпит неудачу, как ожидалось.

Вы можете использовать параметр spec чтобы вызвать ошибку при вызове несуществующего метода:

 @patch("StringIO.StringIO", spec=StringIO.StringIO) def testSomethingNotWorkingAsExpected(self, StringIOMock): StringIOMock.assert_called_once() # will fail as the method doesn't exist 
  • Могу ли я подделывать / издеваться над типом моих макетных объектов в python unittests
  • Как проверить макет звонков с помощью подстановочных знаков?
  • Как утверждать операторы <и> = не реализованы?
  • Настройте зону покрытия.py для использования миграции
  • Можно ли отлаживать отладчик python при использовании py.test?
  • Unittest setUp / tearDown для нескольких тестов
  • Утвердить, что метод был вызван в модульном тесте Python
  • Как мне настроить процесс разработки TDD с помощью Google App Engine?
  • Python - лучший язык программирования в мире.