How to mock a python class dependency using pytest-mock?

  pytest, pytest-mock, python

I am struggling to understand how to stub a class / mock all the methods from a class dependency in Python & pytest. The listing below shows the class that I am testing. It has two internal dependencies: OWMProxy and PyOwmDeserializer.

Class Under Test

class OWM:
    def __init__(self, api_key: str, units: WeatherUnits) -> None:
        self._api_key = api_key
        self._units = units    
        self._pyorm = OWMProxy.from_api_key(api_key)
        self._deserializer = PyOwmDeserializer()

    def at(self, city: str, iso_datetime: str) -> ForecastModel:
        weather = self._pyorm.for_time(city, iso_datetime)

        return self._deserializer.deserialize(weather, self._units)

    def day(self, city: str, day: str) -> ForecastModel:
        weather = self._pyorm.for_day(city, day)

        return self._deserializer.deserialize(weather, self._units)

    def now(self, city: str) -> ForecastModel:
        weather = self._pyorm.now(city) 

        return self._deserializer.deserialize(weather, self._units)

My question is, is it possible to mock an entire class dependency when unit test with PyTest?

Currently, the unit test that I have uses mocker to mock each class method, including init method.

I could use a dependency injection approach, i.e. create an interface for the internal deserializer and proxy interface and add these interfaces to the constructor of the class under test.

Alternatively I could test using unittest.mock module, as suggested here. Is there an equivalent functionality in pytest-mock???

Unit Test So Far…

@pytest.mark.skip(reason="not implemented")
  def test_owm_initialises_deserializer(
      default_weather_units: WeatherUnits, mocker: MockFixture
  ) -> None:
      api_key = "test_api_key"
  
      proxy = OWMProxy(py_OWM(api_key))
  
      patch_proxy = mocker.patch(
          "wayhome_weather_api.openweathermap.client.OWMProxy.from_api_key",
          return_value=proxy,
      )   
  
      patch_val = mocker.patch(
          "wayhome_weather_api.openweathermap.deserializers.PyOwmDeserializer",
          "__init__",
          return_value=None,
      )   
  
      owm = OWM(api_key, default_weather_units)
  
      assert owm is not None

Source: Python Questions

LEAVE A COMMENT