Хорошо, длинная версия: издевательство - это когда вы заменяете что-то упрощенной формой.Тем не менее, вы не можете издеваться над тем, что не было использовано.Это не имеет никакого смысла.
Давайте посмотрим на ваш код здесь:
def a(self,a,b):
ret = B().b()
if ret == True:
return 0
else :
return a+b
Вы создаете новый B () внутри этой функции, поэтому он не имеет return_valueВы устанавливаете в другом месте в тесте на mocked_B.Весь смысл наличия фиктивного объекта в том, что вы передаете имитатор и получаете его предсказуемое поведение.Вы не можете смоделировать объект, который полностью инкапсулирован внутри тестируемой функции.
Здесь я изменил ваш код, чтобы взять (возможно, смоделированный) объект B.Я переименовал целочисленные аргументы из a, b в x, y, потому что это было слишком запутанным.Они не имеют ничего общего с A или B.
Также вы забыли некоторые операции импорта.
import unittest
from unittest.mock import patch
class B :
def __init__(self):
print('hello B')
def b(self):
return False
class A :
def __init__(self):
print('hello A')
def a(self, x, y, b):
if b.b():
return 0
else:
return x + y
class TestA(unittest.TestCase):
def setUp(self):
pass
def return_true(self):
return True
@patch('__main__.B')
def test_a_in_A(self,mocked_B):
mocked_B.b.return_value = True
assert A().a(2,3, mocked_B) == 0
if __name__ == '__main__':
unittest.main()
В соответствии с запросом приведена пересмотренная версия с меньшим влиянием на существующий код:
class A :
def __init__(self, b=None):
# this instance can use a member instance of B
self.b = b if b else B()
print('hello A')
def a(self, x, y):
if self.b.b() is True:
return 0
else:
return x + y
Я изменил тест на «self.bb () - True», чтобы избежать запуска в объекте MagicMock без инициализации return_value, но, тем не менее, оценивается как true, потому что ... это экземпляр, и вот как bool (object)работает.
Здесь вы все равно должны передать в макет экземпляр, в котором значение return_value установлено на то, что вы хотите, поэтому тест будет
assert A(mocked_B).a(2,3) == 0
Вам нужно что-то заменить,если вы хотите, чтобы фиктивный объект что-то заменил.Это может помочь найти «внедрение зависимостей», которое является еще одним названием той же основной идеи.