При условии следующей настройки:
class A:
def __init__(self, nodes):
self.nodes=nodes
def update(self, bool_a=True):
if bool_a:
for n in self.nodes:
if hasattr(self.nodes[n], 'update'):
self.nodes[n].update()
class B:
def __init__(self, int_attr=5):
self.int_attr=int_attr
def update(self):
self.int_attr = 0
Предположим, что список узлов в классе A фактически является списком экземпляров класса B.
Как мне написать модульный тест для метода обновления класса A, чтобы проверить, был ли вызван метод обновления каждого узла класса B, содержащегося в self.nodes класса A?
В более общей настройке предположим, что существует несколько классов, реализующих метод обновления, и они могут быть узлами в пределах self.nodes класса A. Как проверить, что были вызваны все методы обновления членов self.nodes?
Я безуспешно пробовал следующее:
mock_obj = MagicMock()
@patch('module.A.update', return_value=mock_obj)
def test_update(self, mock_obj):
nodes = {}
nodes['first'] = B(int_attr=1)
nodes['second'] = B(int_attr=2)
test_A = module.A(nodes=nodes)
test_A.update(bool_A=True)
self.assertTrue(mock_obj.called)
как предложено в насмешка над функцией в методе класса .
Редактировать: Если мы примем этот конкретный случай:
import unittest
import mock
from unittest import TestCase
class A:
def __init__(self, nodes):
self.nodes=nodes
def update(self, bool_a=True):
if bool_a:
to_update = [n for n in self.nodes]
while len(to_update) > 0:
if hasattr(self.nodes[to_update[-1]], 'update'):
self.nodes[to_update[-1]].update()
print('Update called.')
if self.nodes[to_update[-1]].is_updated:
to_update.pop()
class B:
def __init__(self, int_attr=5):
self.int_attr=int_attr
self.is_updated = False
def update(self):
self.int_attr = 0
self.is_updated = True
class TestEnsemble(TestCase):
def setUp(self):
self.b1 = B(1)
self.b2 = B(2)
self.b3 = B(3)
self.nodes = {}
self.nodes['1'] = self.b1
self.nodes['2'] = self.b2
self.nodes['3'] = self.b3
self.a = A(self.nodes)
@mock.patch('module.B.update')
def test_update(self, mock_update):
mock_update.return_value = None
self.a.update()
with self.subTest():
self.assertEqual(mock_update.call_count, 3)
Запуск unittest для этого случая приводит к бесконечному циклу, поскольку атрибут is_updated никогда не устанавливается в True, поскольку метод обновления класса B является ложным. Как измерить количество времени, в течение которого B.update был вызван в A.update?
Обновление:
Пробовал это:
@mock.patch('dummy_script.B')
def test_update(self, mock_B):
self.a.update()
with self.subTest():
self.assertEqual(mock_B.update.call_count, 3)
Функция обновления теперь действительно запускается 3 раза (я вижу это в выводе консоли, так как «Обновление вызвано.» Выводится три раза), но call_count метода update остается нулевым. Я проверяю неправильный атрибут / объект?