I'm new to the mocking library and so far it's been giving me trouble. I'm trying to test a Url parsing method that takes a response from an initialUrl
which is then parsed in the method. I set autospec=true
so I think it should have access to all methods in the requests library (including response.url
) I'm trying to mock both get
and response
though I'm not sure if that's needed?
My getUrl method that takes a response and returns its parsed contents:
def getUrl(response):
if response.history:
destination = urllib.parse.urlsplit(response.url)
baseUrlTuple = destination._replace(path="", query="")
return urllib.parse.urldefrag(urllib.parse.urlunsplit(baseUrlTuple)).url
raise RuntimeError("No redirect")
Test method:
def testGetUrl(self):
initialUrl = 'http://www.initial-url.com'
expectedUrl = 'http://www.some-new-url.com'
mock_response = Mock(spec=requests, autospec=True)
mock_response.status_code = 200
mock_get = Mock(return_value=mock_response)
#mock_get.return_value.history = True
resp = mock_get(self.initialUrl)
mock_response.history = True
resultUrl = getBaseUrl(resp)
self.assertEqual(resultUrl, expectedUrl)
When I run the test, I get
raise AttributeError("Mock object has no attribute %r" % name)
AttributeError: Mock object has no attribute 'url'
First I would fix the code in your question so that it actually runs.
You have several options, the easiest being just adding url
to the list of attributes you're mocking:
mock_response.url = <your URL>
But it's also important to understand that you're trying to use the requests library as a specification for the mock, when you should be using requests.Response()
if you want the url attribute to be automatically generated. You still have to assign whatever url you want to use to it though, or you'll be comparing a Mock object to an int in your function.
Take a look at the documentation involving spec if you want to learn more: https://docs.python.org/3/library/unittest.mock-examples.html