Насмешливые значения по умолчанию attr.ib()

У меня ситуация похожа на следующую

@attrs(auto_attribs=True)
class ExampleClass:
  _prop: OtherClass = attrib(init=False, default=OtherClass())
  def some_func(self):
    test_var = OtherClass()
    test_var.some_func()
    self._prop.some_func()

class OtherClass:
  def some_func(self):
    raise NotImplementedException

def test_example(mocker):
  mocker.patch("path.to.example_class.OtherClass")
  sut = ExampleClass()
  sut.some_func()

Все классы и тесты находятся в разных файлах, и mocker - это приспособление, предоставляемое pytest_mock, которое является просто оболочкой для unittest.mock, которая облегчает очистку.

Проблема, с которой я сталкиваюсь, заключается в том, что при запуске модульных тестов test_var правильно назначается как MagicMock из функции патча. Так что когда test_var.some_func() возвращается, все в порядке.

когда self._prop.some_func() называется, NotImplementedException поднимается, как кажется, что патч не влияет на это.

В моем модульном тесте я мог установить sut._prop = MagicMock() но это внутренняя деталь реализации, делающая его хрупким тестом.

Как избежать насмешек над переменной по умолчанию в атрибуте, чтобы избежать этого?

1 ответ

Решение

Я использовал библиотеку функционально неправильно, так как я устанавливал значение по умолчанию для экземпляра, когда я каждый раз хотел новый экземпляр. Изменение класса ExampleClass на следующее устраняет мою проблему

@attrs(auto_attribs=True)
class ExampleClass:
  _prop: OtherClass = attrib(init=False, factory=lambda: OtherClass())
  def some_func(self):
    test_var = OtherClass()
    test_var.some_func()
    self._prop.some_func()
Другие вопросы по тегам