Как создать экземпляр mocked class в другом классе

#python #unit-testing #mocking

#python #модульное тестирование #издевательство

Вопрос:

Класс A имеет атрибут другого класса B.

 Class A():
   def __init__(self, b):
      self.b = b

   def get_b_secret(self, job_id):
      x, y = self.b.get_secret(job_id)
      return x, y

Class B():
   def __init__(self, key, url):
      self.key = key
      self.url = url
   def get_secret(job_id):
      # logic to get secret
      # return a tuple
      return x, y
 

Я хочу написать модульный тест для метода get_b_secret класса A, имитируя класс B в целом.

 @patch('b.B')
def test_get_b_secret(self, mock_b):
    mock_b.b.get_secret.return_value = ('x', 'y')
    obj = A(mock_b) 
    expected = ('x','y')
    self.assertEqual(obj.get_b_secret('001'), expected)
 

Я понял, что, издеваясь над классом B, я на самом деле не создаю экземпляр B для экземпляра внутри экземпляра A. Вот почему, когда я отлаживаю тест, A ‘s get_b_secret вместо этого возвращает MagicMock объект.

Я нашел эту статью о mocking object . Но в этом примере init внешнего класса не имеет объекта внутреннего класса в качестве аргумента. Так что это немного по-другому. Каков наилучший способ сделать это?

Ответ №1:

Если ваш пример кода правильный, вам не нужно имитировать класс B. Вам просто нужно передать макет с помощью функции get_secret в класс A при его инициализации.

 mock = MagicMock()    

mock.return_value.get_secret.return_value = ('x', 'y')
obj = A(mock)
....
 

Комментарии:

1. Я думаю, что первое return-value не обязательно