title: Having trouble mocking a request in a class method using patch context manager in Python
body: <p>I am trying to unit test a class method that makes an API request and returns a json file that is loaded into a variable as a dictionary. The request returns a json file as requested. Another test that I would like to implement is that it is accessing the correct link. I am using patch as a context manager with the mock module.</p>
  <p>In summary, my app snowReport.py accesses a weather API that returns a weatherJson, and then it accesses that Json to determine if there will be snow in the forecast. The class is called Resort because it is meant specifically for ski resorts.</p>
  <p>In my module, this is my <code>__init__</code> function.</p>
  <pre><code>class Resort():
      # kwargs is created so the user can pass in &quot;96hr&quot;, &quot;realtime&quot;, and or &quot;360min&quot;
      def __init__(self, resortKey, *args):
          # Check if you are in the current directory, if not, set it to the current directory
          currentDir = os.getcwd()
  
          if currentDir != D_NAME:
              os.chdir(D_NAME)
          else:
              pass
  
          # Checks if the user enters arguments to initiate json files or not
          self.dataJSON = SKI_RESORT_JSON
          self.args = args
  
          if not args:
              raise Exception(&quot;Invalid arg passed. Function arguments must contain one of '360min' and/or '96hr' and/or 'realtime'&quot;) # Note there is a hidden arg that is called test that does not access the api to do a mock test
  
          # Opens json file to get location parameters
          with open(SKI_RESORT_JSON, &quot;r&quot;) as f:
              resortDictList = json.load(f)
              resortDict = resortDictList[resortKey]
  
          self.name = resortDict[&quot;name&quot;]
          self.lon = resortDict[&quot;lon&quot;]
          self.lat = resortDict[&quot;lat&quot;]
          self.country = resortDict[&quot;country&quot;]
  
          self.weatherJsonRealTime = {}
          self.weatherJson360Min = {}
          self.weatherJson96hr = {}
  </code></pre>
  <p>The purpose of this <code>__init_</code>_ function is to initialize variables and access a .json file where it pulls the location data.</p>
  <p>The function I am trying to test is a class method that is the following:</p>
  <pre><code>def requestRealtime(self):
          querystring = {
              &quot;lat&quot;: str(self.lat),
              &quot;lon&quot;: str(self.lon),
              &quot;unit_system&quot;: &quot;si&quot;,
              &quot;fields&quot;: &quot;precipitation,precipitation_type,temp,feels_like,wind_speed,wind_direction,sunrise,sunset,visibility,cloud_cover,cloud_base,weather_code&quot;,
              &quot;apikey&quot;: CLIMACELL_KEY,
          }
  
          response = requests.request(&quot;GET&quot;, URL_REALTIME, params=querystring)
  
          if response.ok:
              self.weatherJsonRealTime = json.load(response.text)
          else:
              return &quot;Bad response&quot;
  
          self.nowTime = localTime(self.weatherJsonRealTime[&quot;observation_time&quot;][&quot;value&quot;])
          self.nowTemp = self.weatherJsonRealTime[&quot;temp&quot;][&quot;value&quot;]
          self.nowFeelsLike = self.weatherJsonRealTime[&quot;feels_like&quot;][&quot;value&quot;]
          self.nowPrecipitation = self.weatherJsonRealTime[&quot;precipitation&quot;][&quot;value&quot;]
          self.nowPrecipitationType = self.weatherJsonRealTime[&quot;precipitation_type&quot;][&quot;value&quot;]
          self.nowWindSpeed = self.weatherJsonRealTime[&quot;wind_speed&quot;][&quot;value&quot;]
          self.nowWindDirection = self.weatherJsonRealTime[&quot;wind_direction&quot;][&quot;value&quot;]
          self.nowCloudCover = self.weatherJsonRealTime[&quot;cloud_cover&quot;][&quot;value&quot;]
  
          return self.weatherJsonRealTime  
  </code></pre>
  <p>I am trying to test the request, more specifically, I am trying to test that the request. To do so, I am using the patch context manager to mock the request.requests and set the return value to be a static test json file. My test code is as follows:</p>
  <pre><code>with open(&quot;.\\Resources\\test_realtimeJson.json&quot;, &quot;r&quot;) as f:
      testrealtimeDict = json.load(f)
      
  @classmethod
      def setUpClass(cls):
          cls.testResort = snowReport.Resort(&quot;test_Location (Banff)&quot;, &quot;96hr&quot;, &quot;realtime&quot;, &quot;360min&quot;)
          os.chdir(D_NAME) # Set the directory back to D_NAME because that the snowReport.Resort class changes it's class
  
  
      def test_requestRealtime(self):
          with patch(&quot;snowApp.snowReport.requests.request&quot;) as mocked_request:
              mocked_request.return_value.ok = True
              mocked_request.return_value.request = testrealtimeDict
              self.testResort.requestRealtime()
  </code></pre>
  <p>Assuming the mock works, I would then like to use the assertEqual function to test and see if the attributes that are created in the snowReport function returns the expected value based on the dictionary that I pass it.</p>
  <p>When I run the test script, it throws me the error:</p>
  <pre><code>File &quot;c:\users\steve\appdata\local\programs\python\python39\lib\json\__init__.py&quot;, line 339, in loads
      raise TypeError(f'the JSON object must be str, bytes or bytearray, '
  TypeError: the JSON object must be str, bytes or bytearray, not MagicMock
  </code></pre>
  <p>Since I am mocking the request and setting the return value to the testrealtimeDict that I have created, shouldn't self.weatherJsonRealtime = testrealtimeDict? Why is it throwing the type error? Also - is the unit test that I am planning appropriate for this application or is there a better or easier way to complete this?</p>